package data /* Data package: Handles data from text to number, and vice versa */ import ( "fmt" "config" "strings" "strconv" "tools/rsa/integer" ) type Data string type DataType int const ( LL = config.RSA_SIZE AE = config.AE OE = config.OE AA = config.AA SPACE = config.SPACE COMMA = config.COMMA DOT = config.DOT PAD = SPACE NUM DataType = 1 << iota TXT DataType = 1 << iota ) type Blob struct { d Data t DataType } func New() *Blob { return new(Blob) } func (b *Blob) Data() *Data { return &b.d } func (b *Blob) Set(t DataType, s Data) *Blob{ b.t = t b.Data().set(s) return b } func (b *Blob) AsNumbers() *Blob { if b.t == NUM { return b } b.Set(NUM, Data( strings.Map(func (c rune) rune { switch c { case 'æ': c = AE case 'ø': c = OE case 'å': c = AA case ' ': c = SPACE case ',': c = COMMA case '.': c = DOT default: c %= 97 } return c }, string(b.Data().Get())), ), ) b.Data().pad() return b } func (b *Blob) AsText() *Blob { if b.t == TXT { return b } b.Set(TXT, Data( strings.Map(func (c rune) rune { switch c { case AE: c = 'æ' case OE: c = 'ø' case AA: c = 'å' case SPACE: c = ' ' case COMMA: c = ',' case DOT: c = '.' default: c += 97 } return c }, string(b.Data().Get())), ), ) return b } func (b *Blob) ToList() []*integer.RSAInt { var l []*integer.RSAInt for s, i := strings.Split(b.Repr(), "\n"), 0; i < len(s); i++ { rint, _ := integer.New(0).SetString(s[i]) l = append(l, rint) } return l } func (b *Blob) FromList(l []*integer.RSAInt) { str := "" for x := 0; x < len(l); x++ { if l[x].Len() < LL { str += "0" + l[x].String() } else { str += l[x].String() } } b.Data().SetRaw(str) } func (b *Blob) Repr() string { s := "" if b.t == TXT { s = string(b.Data().Get()) } else { for i := 0; i < b.Data().Len(); i++ { if (i % (LL / 2)) == 0 { s += "\n" } s += fmt.Sprintf("%.2d", b.Data().Get()[i]) } } return strings.Trim(s, "\n") } func (d *Data) set(s Data) { *d = s } func (d *Data) SetRaw(s string) { raw := "" for y := 0; y < len(s); y += 2 { yy := y+2 if yy > len(s) { yy = len(s) } a, _ := strconv.Atoi(s[y:yy]) raw += fmt.Sprintf("%c", (rune(a))) } d.set(Data(raw)) } func (d *Data) add(s Data) { *d += s } func (d *Data) Get() Data { return *d } func (d *Data) Len() int { return len(d.Get()) } func (d *Data) pad () { l := d.Len() * 2 ll := l % LL if ll == 0 { return } for m, i := LL - ll, 0; i < m; i += 2 { d.add(Data(PAD)) } }