11package encode
22
3- import "github.com/codeharik/secretary/utils"
3+ import (
4+ "strings"
5+
6+ "github.com/codeharik/secretary/utils"
7+ )
48
59var SEC32KeyMap = [][]byte {
610 /*00*/ {'~' },
711 /*01*/ {'a' , 'A' },
812 /*02*/ {'p' , 'P' , 'b' , 'B' , '+' },
9- /*03*/ {'c' , 'C' , 's' , 'S' , ':' },
13+ /*03*/ {'c' , 'C' , 's' , 'S' },
1014 /*04*/ {'d' , 'D' , '/' },
1115 /*05*/ {'e' , 'E' , '=' },
1216 /*06*/ {'i' , 'I' },
13- /*07*/ {'f' , 'F' , '"' , '\'' },
14- /*08*/ {'g' , 'G' , 'j' , 'J' , 'x' , 'X' , ' z' , 'Z' },
17+ /*07*/ {'f' , 'F' },
18+ /*08*/ {'g' , 'G' , 'j' , 'J' , 'z' , 'Z' },
1519 /*09*/ {'h' , 'H' , '%' },
1620 /*10*/ {'o' , 'O' },
17- /*11*/ {'k' , 'K' , 'q' , 'Q' , '?' , '!' , '\\' , '|' },
18- /*12*/ {'l' , 'L' , '&' , '@' },
19- /*13*/ {'m' , 'M' , '- ' },
20- /*14*/ {'n' , 'N' , '* ' },
21+ /*11*/ {'k' , 'K' , 'q' , 'Q' }, // '?', '!', '\\', '|','&', '@','#','$','^ '},
22+ /*12*/ {'l' , 'L' },
23+ /*13*/ {'m' , 'M' , '* ' },
24+ /*14*/ {'n' , 'N' , '- ' },
2125 /*15*/ {'t' , 'T' },
22- /*16*/ {'r' , 'R' , '^' },
23- /*17*/ {'u' , 'U' , 'v' , 'V' , '#' },
24- /*18*/ {'w ' , 'W ' , 'y' , 'Y' , '$ ' },
26+ /*16*/ {'r' , 'R' },
27+ /*17*/ {'u' , 'U' , 'v' , 'V' },
28+ /*18*/ {'x ' , 'X ' , 'y' , 'Y' , 'w' , 'W ' },
2529 /*19*/ {'0' },
2630 /*20*/ {'1' },
2731 /*21*/ {'2' },
@@ -34,10 +38,13 @@ var SEC32KeyMap = [][]byte{
3438 /*28*/ {'9' },
3539 /*29*/ {'(' , '[' , '<' , '{' },
3640 /*30*/ {')' , ']' , '>' , '}' },
37- /*31*/ {'_' , '.' , ',' , ';' , ' ' , '\n' },
41+ /*31*/ {'_' , '.' , ',' , ';' , ' ' , '\n' , '"' , '\'' , '`' , ':' },
3842}
3943
40- const SEC32 = `-apcdeifghoklmntruw0123456789QR_`
44+ var (
45+ ASCII32 = [32 ]byte {}
46+ SEC32 = []byte (`-apcdeifghoklmntrux0123456789QR_` )
47+ )
4148
4249var (
4350 ASCII32Index = [256 ]byte {}
@@ -50,57 +57,145 @@ func init() {
5057 SEC32Index [i ] = 0
5158 }
5259 for index , chars := range SEC32KeyMap {
60+ ASCII32 [index ] = chars [0 ]
5361 SEC32Index [SEC32 [index ]] = byte (index )
5462 for _ , c := range chars {
5563 ASCII32Index [c ] = byte (index )
5664 }
5765 }
5866}
5967
60- func AsciiToSec32 (str string ) string {
68+ func StringToSec32 (str string ) string {
6169 return string (utils .Map (
6270 []byte (str ),
6371 func (c byte ) byte {
6472 return SEC32 [ASCII32Index [c ]]
6573 }))
6674}
6775
68- func Ascii32ToIndex (str string ) []byte {
76+ func StringToIndex32 (str string ) []byte {
6977 return utils .Map (
7078 []byte (str ),
7179 func (c byte ) byte {
7280 return ASCII32Index [c ]
7381 })
7482}
7583
76- func IndexToAscii32 (arr []byte ) string {
84+ func StringToIndex32Packed (str string ) []byte {
85+ return Pack8to5 (StringToIndex32 (str ))
86+ }
87+
88+ func Index32ToAscii32 (indexes []byte ) string {
7789 return string (utils .Map (
78- arr ,
90+ indexes ,
7991 func (i byte ) byte {
80- return SEC32KeyMap [ i ][ 0 ]
92+ return ASCII32 [ i ]
8193 }))
8294}
8395
84- func Sec32ToAscii (str string ) string {
96+ func Index32PackedToAscii32 (indexes []byte ) string {
97+ return Index32ToAscii32 (Unpack5to8 (indexes ))
98+ }
99+
100+ func Sec32ToAscii32 (str string ) string {
85101 return string (utils .Map (
86102 []byte (str ),
87103 func (c byte ) byte {
88- return SEC32KeyMap [SEC32Index [c ]][ 0 ]
104+ return ASCII32 [SEC32Index [c ]]
89105 }))
90106}
91107
92- func Sec32ToIndex (str string ) []byte {
108+ func Sec32ToIndex32 (str string ) []byte {
93109 return utils .Map (
94110 []byte (str ),
95111 func (c byte ) byte {
96112 return SEC32Index [c ]
97113 })
98114}
99115
100- func IndexToSec32 (arr []byte ) string {
116+ func Sec32ToIndex32Packed (str string ) []byte {
117+ return Pack8to5 (Sec32ToIndex32 (str ))
118+ }
119+
120+ func Index32ToSec32 (indexes []byte ) string {
101121 return string (utils .Map (
102- arr ,
122+ indexes ,
103123 func (i byte ) byte {
104124 return SEC32 [i ]
105125 }))
106126}
127+
128+ func Index32PackedToSec32 (indexes []byte ) string {
129+ return Index32ToSec32 (Unpack5to8 (indexes ))
130+ }
131+
132+ func ExpandStringToSec32 (str string ) string {
133+ unpacked := Unpack5to8 ([]byte (str ))
134+ enc := make ([]byte , len (unpacked ))
135+ for i := 0 ; i < len (unpacked ); i ++ {
136+ enc [i ] = SEC32 [unpacked [i ]]
137+ }
138+ return string (enc )
139+ }
140+
141+ func Sec32ToExpandString (str string ) string {
142+ packed := Pack8to5 (Sec32ToIndex32 (str ))
143+ return strings .Trim (string (packed ), "\x00 " )
144+ }
145+
146+ // 87654321 | 87654321 | 87654321 | 87654321 | 87654321 | 87654321 | 87654321 | 87654321
147+ // Encode
148+ // 0,5 1,3 1,2 2,5 3,1 3,4 4,4 4,1 5,5 6,2 6,3 7,5
149+ // 54321 543 | 21 54321 5 | 4321 5432 | 1 54321 54 | 321 54321
150+ // Pack8to5 converts 8-bit bytes into 5-bit packed format
151+ func Pack8to5 (input []byte ) []byte {
152+ // Calculate the number of bytes needed for the packed output
153+ // Each 8 bits (1 byte) will produce 5 bits, so we need to round up
154+ // the number of input bytes to the nearest multiple of 8.
155+ e := len (input ) % 8
156+ if e != 0 {
157+ input = append (input , make ([]byte , 8 - e )... )
158+ }
159+
160+ // The length of the packed output will be (5/8) * len(input)
161+ packed := make ([]byte , (5 * len (input ))/ 8 )
162+
163+ for u , p := 0 , 0 ; u < len (input ); u += 8 {
164+ packed [p ] = (input [u ]& 0b00011111 )<< 3 | (input [u + 1 ]& 0b00011100 )>> 2
165+ packed [p + 1 ] = (input [u + 1 ]& 0b00000011 )<< 6 | (input [u + 2 ]& 0b00011111 )<< 1 | (input [u + 3 ]& 0b00010000 )>> 4
166+ packed [p + 2 ] = input [u + 3 ]<< 4 | (input [u + 4 ]& 0b00011110 )>> 1
167+ packed [p + 3 ] = (input [u + 4 ]& 0b00000001 )<< 7 | (input [u + 5 ]& 0b00011111 )<< 2 | (input [u + 6 ]& 0b00011000 )>> 3
168+ packed [p + 4 ] = input [u + 6 ]<< 5 | (input [u + 7 ] & 0b00011111 )
169+ p += 5
170+ }
171+
172+ return packed
173+ }
174+
175+ // Encode
176+ // 54321 543 | 21 54321 5 | 4321 5432 | 1 54321 54 | 321 54321
177+ // Decode
178+ // 0,5 0,3 1,2 1,5 1,1 2,4 2,4 3,1 3,5 3,2 4,3 4,5
179+ // 00054321 | 00054321 | 00054321 | 00054321 | 00054321 | 00054321 | 00054321 | 00054321
180+ func Unpack5to8 (packed []byte ) []byte {
181+ e := len (packed ) % 5
182+ if e != 0 {
183+ packed = append (packed , make ([]byte , 5 - e )... )
184+ }
185+
186+ unpacked := make ([]byte , (8 * len (packed ))/ 5 )
187+
188+ for u , p := 0 , 0 ; p < len (packed ); p += 5 {
189+ unpacked [u ] = packed [p ] >> 3
190+ unpacked [u + 1 ] = (packed [p ]<< 2 | packed [p + 1 ]>> 6 ) & 0b00011111
191+ unpacked [u + 2 ] = (packed [p + 1 ] >> 1 ) & 0b00011111
192+ unpacked [u + 3 ] = (packed [p + 1 ]<< 4 | packed [p + 2 ]>> 4 ) & 0b00011111
193+ unpacked [u + 4 ] = (packed [p + 2 ]<< 1 | packed [p + 3 ]>> 7 ) & 0b00011111
194+ unpacked [u + 5 ] = (packed [p + 3 ] >> 2 ) & 0b00011111
195+ unpacked [u + 6 ] = (packed [p + 3 ]<< 3 | packed [p + 4 ]>> 5 ) & 0b00011111
196+ unpacked [u + 7 ] = packed [p + 4 ] & 0b00011111
197+ u += 8
198+ }
199+
200+ return unpacked
201+ }
0 commit comments