@@ -3,22 +3,25 @@ package LZString
3
3
import (
4
4
"errors"
5
5
"math"
6
+ "strings"
7
+ "sync"
6
8
"unicode/utf8"
7
9
)
8
10
9
11
// Compress
12
+ const _defaultKeyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
10
13
11
- var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
12
-
13
- func CompressToBase64 (uncompressed string ) string {
14
+ func Compress (uncompressed string , keyStrBase64 string ) string {
14
15
if len (uncompressed ) == 0 {
15
16
return ""
16
17
}
17
-
18
- res := Compress (uncompressed , 6 , func (character int ) string {
19
- return string ([]rune (keyStrBase64 )[character ])
18
+ if keyStrBase64 == "" {
19
+ keyStrBase64 = _defaultKeyStrBase64
20
+ }
21
+ charArr := []rune (keyStrBase64 )
22
+ res := _compress (uncompressed , 6 , func (character int ) string {
23
+ return string (charArr [character ])
20
24
})
21
-
22
25
switch len (res ) % 4 {
23
26
default :
24
27
case 0 :
@@ -33,7 +36,7 @@ func CompressToBase64(uncompressed string) string {
33
36
return res
34
37
}
35
38
36
- func Compress (uncompressed string , bitsPerChar int , getCharFromInt func (character int ) string ) string {
39
+ func _compress (uncompressed string , bitsPerChar int , getCharFromInt func (character int ) string ) string {
37
40
if len (uncompressed ) == 0 {
38
41
return ""
39
42
}
@@ -46,44 +49,48 @@ func Compress(uncompressed string, bitsPerChar int, getCharFromInt func(characte
46
49
contextEnlargeIn := float64 (2 )
47
50
contextDictSize := int (3 )
48
51
contextNumBits := int (2 )
49
- var contextDataString string
52
+ //var contextDataString string
53
+ var contextDataString = strings.Builder {}
54
+
50
55
contextDataVal := int (0 )
51
56
contextDataPosition := int (0 )
52
57
53
- for ii := 0 ; ii < len ([]rune (uncompressed )); ii ++ {
54
- contextC = string ([]rune (uncompressed )[ii ])
58
+ uncompressedRunes := []rune (uncompressed )
59
+ for ii := 0 ; ii < len (uncompressedRunes ); ii ++ {
60
+ contextC = string (uncompressedRunes [ii ])
55
61
_ , in := contextDictionary [contextC ]
56
62
if ! in {
57
63
contextDictionary [contextC ] = contextDictSize
58
64
contextDictSize ++
59
65
contextDictionaryToCreate [contextC ] = true
60
66
}
61
-
62
67
contextWc = contextW + contextC
63
-
64
68
_ , in = contextDictionary [contextWc ]
65
69
if in {
66
70
contextW = contextWc
67
71
} else {
68
72
_ , in = contextDictionaryToCreate [contextW ]
69
73
if in {
70
- if []rune (contextW )[0 ] < 256 {
74
+ contextWRune := []rune (contextW )
75
+ if contextWRune [0 ] < 256 {
71
76
for i := 0 ; i < contextNumBits ; i ++ {
72
77
contextDataVal = contextDataVal << 1
73
78
if contextDataPosition == bitsPerChar - 1 {
74
79
contextDataPosition = 0
75
- contextDataString += getCharFromInt (contextDataVal )
80
+ //contextDataString += getCharFromInt(contextDataVal)
81
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
76
82
contextDataVal = 0
77
83
} else {
78
84
contextDataPosition ++
79
85
}
80
86
}
81
- value = int ([] rune ( contextW ) [0 ])
87
+ value = int (contextWRune [0 ])
82
88
for i := 0 ; i < 8 ; i ++ {
83
89
contextDataVal = (contextDataVal << 1 ) | (value & 1 )
84
90
if contextDataPosition == bitsPerChar - 1 {
85
91
contextDataPosition = 0
86
- contextDataString += getCharFromInt (contextDataVal )
92
+ //contextDataString += getCharFromInt(contextDataVal)
93
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
87
94
contextDataVal = 0
88
95
} else {
89
96
contextDataPosition ++
@@ -96,19 +103,21 @@ func Compress(uncompressed string, bitsPerChar int, getCharFromInt func(characte
96
103
contextDataVal = (contextDataVal << 1 ) | value
97
104
if contextDataPosition == bitsPerChar - 1 {
98
105
contextDataPosition = 0
99
- contextDataString += getCharFromInt (contextDataVal )
106
+ //contextDataString += getCharFromInt(contextDataVal)
107
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
100
108
contextDataVal = 0
101
109
} else {
102
110
contextDataPosition ++
103
111
}
104
112
value = 0
105
113
}
106
- value = int ([] rune ( contextW ) [0 ])
114
+ value = int (contextWRune [0 ])
107
115
for i := 0 ; i < 16 ; i ++ {
108
116
contextDataVal = (contextDataVal << 1 ) | (value & 1 )
109
117
if contextDataPosition == bitsPerChar - 1 {
110
118
contextDataPosition = 0
111
- contextDataString += getCharFromInt (contextDataVal )
119
+ //contextDataString += getCharFromInt(contextDataVal)
120
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
112
121
contextDataVal = 0
113
122
} else {
114
123
contextDataPosition ++
@@ -128,7 +137,8 @@ func Compress(uncompressed string, bitsPerChar int, getCharFromInt func(characte
128
137
contextDataVal = (contextDataVal << 1 ) | (value & 1 )
129
138
if contextDataPosition == bitsPerChar - 1 {
130
139
contextDataPosition = 0
131
- contextDataString += getCharFromInt (contextDataVal )
140
+ //contextDataString += getCharFromInt(contextDataVal)
141
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
132
142
contextDataVal = 0
133
143
} else {
134
144
contextDataPosition ++
@@ -155,7 +165,8 @@ func Compress(uncompressed string, bitsPerChar int, getCharFromInt func(characte
155
165
contextDataVal = contextDataVal << 1
156
166
if contextDataPosition == bitsPerChar - 1 {
157
167
contextDataPosition = 0
158
- contextDataString += getCharFromInt (contextDataVal )
168
+ //contextDataString += getCharFromInt(contextDataVal)
169
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
159
170
contextDataVal = 0
160
171
} else {
161
172
contextDataPosition ++
@@ -166,7 +177,8 @@ func Compress(uncompressed string, bitsPerChar int, getCharFromInt func(characte
166
177
contextDataVal = (contextDataVal << 1 ) | (value & 1 )
167
178
if contextDataPosition == bitsPerChar - 1 {
168
179
contextDataPosition = 0
169
- contextDataString += getCharFromInt (contextDataVal )
180
+ //contextDataString += getCharFromInt(contextDataVal)
181
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
170
182
contextDataVal = 0
171
183
} else {
172
184
contextDataPosition ++
@@ -179,7 +191,8 @@ func Compress(uncompressed string, bitsPerChar int, getCharFromInt func(characte
179
191
contextDataVal = (contextDataVal << 1 ) | value
180
192
if contextDataPosition == bitsPerChar - 1 {
181
193
contextDataPosition = 0
182
- contextDataString += getCharFromInt (contextDataVal )
194
+ //contextDataString += getCharFromInt(contextDataVal)
195
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
183
196
contextDataVal = 0
184
197
} else {
185
198
contextDataPosition ++
@@ -191,7 +204,8 @@ func Compress(uncompressed string, bitsPerChar int, getCharFromInt func(characte
191
204
contextDataVal = (contextDataVal << 1 ) | (value & 1 )
192
205
if contextDataPosition == bitsPerChar - 1 {
193
206
contextDataPosition = 0
194
- contextDataString += getCharFromInt (contextDataVal )
207
+ //contextDataString += getCharFromInt(contextDataVal)
208
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
195
209
contextDataVal = 0
196
210
} else {
197
211
contextDataPosition ++
@@ -211,7 +225,8 @@ func Compress(uncompressed string, bitsPerChar int, getCharFromInt func(characte
211
225
contextDataVal = (contextDataVal << 1 ) | (value & 1 )
212
226
if contextDataPosition == bitsPerChar - 1 {
213
227
contextDataPosition = 0
214
- contextDataString += getCharFromInt (contextDataVal )
228
+ //contextDataString += getCharFromInt(contextDataVal)
229
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
215
230
contextDataVal = 0
216
231
} else {
217
232
contextDataPosition ++
@@ -231,7 +246,8 @@ func Compress(uncompressed string, bitsPerChar int, getCharFromInt func(characte
231
246
contextDataVal = (contextDataVal << 1 ) | (value & 1 )
232
247
if contextDataPosition == bitsPerChar - 1 {
233
248
contextDataPosition = 0
234
- contextDataString += getCharFromInt (contextDataVal )
249
+ //contextDataString += getCharFromInt(contextDataVal)
250
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
235
251
contextDataVal = 0
236
252
} else {
237
253
contextDataPosition ++
@@ -242,21 +258,22 @@ func Compress(uncompressed string, bitsPerChar int, getCharFromInt func(characte
242
258
for {
243
259
contextDataVal = contextDataVal << 1
244
260
if contextDataPosition == bitsPerChar - 1 {
245
- contextDataString += getCharFromInt (contextDataVal )
261
+ //contextDataString += getCharFromInt(contextDataVal)
262
+ contextDataString .WriteString (getCharFromInt (contextDataVal ))
246
263
break
247
264
} else {
248
265
contextDataPosition ++
249
266
}
250
267
}
251
- return contextDataString
268
+ return contextDataString . String ()
252
269
}
253
270
254
271
// Decompress
255
-
256
- var keyStrBase64Map map [byte ]int = map [byte ]int {74 : 9 , 78 : 13 , 83 : 18 , 61 : 64 , 109 : 38 , 114 : 43 , 116 : 45 , 101 : 30 , 47 : 63 , 73 : 8 , 81 : 16 , 113 : 42 , 49 : 53 , 50 : 54 , 54 : 58 , 76 : 11 , 100 : 29 , 107 : 36 , 121 : 50 , 77 : 12 , 89 : 24 , 105 : 34 , 66 : 1 , 69 : 4 , 85 : 20 , 48 : 52 , 119 : 48 , 117 : 46 , 120 : 49 , 52 : 56 , 56 : 60 , 110 : 39 , 112 : 41 , 70 : 5 , 71 : 6 , 79 : 14 , 88 : 23 , 97 : 26 , 102 : 31 , 103 : 32 , 67 : 2 , 118 : 47 , 65 : 0 , 68 : 3 , 72 : 7 , 108 : 37 , 51 : 55 , 57 : 61 , 82 : 17 , 90 : 25 , 98 : 27 , 115 : 44 , 122 : 51 , 53 : 57 , 86 : 21 , 106 : 35 , 111 : 40 , 55 : 59 , 43 : 62 , 75 : 10 , 80 : 15 , 84 : 19 , 87 : 22 , 99 : 28 , 104 : 33 }
272
+ var baseReverseDic = sync.Map {}
257
273
258
274
type dataStruct struct {
259
275
input string
276
+ alphabet string
260
277
val int
261
278
position int
262
279
index int
@@ -265,8 +282,25 @@ type dataStruct struct {
265
282
numBits int
266
283
}
267
284
268
- func getBaseValue (char byte ) int {
269
- return keyStrBase64Map [char ]
285
+ func covertToBaseReverseDic (alphabet string ) map [byte ]int {
286
+ var val = map [byte ]int {}
287
+ charArr := []rune (alphabet )
288
+ for i := 0 ; i < len (charArr ); i ++ {
289
+ val [byte (charArr [i ])] = i
290
+ }
291
+ return val
292
+ }
293
+
294
+ func getBaseValue (alphabet string , char byte ) int {
295
+ vv , ok := baseReverseDic .Load (alphabet )
296
+ var arr map [byte ]int
297
+ if ok {
298
+ arr = vv .(map [byte ]int )
299
+ } else {
300
+ arr = covertToBaseReverseDic (alphabet )
301
+ baseReverseDic .Store (alphabet , arr )
302
+ }
303
+ return arr [char ]
270
304
}
271
305
272
306
// Input is composed of ASCII characters, so accessing it by array has no UTF-8 pb.
@@ -278,7 +312,7 @@ func readBits(nb int, data *dataStruct) int {
278
312
data .position = data .position / 2
279
313
if data .position == 0 {
280
314
data .position = 32
281
- data .val = getBaseValue (data .input [data .index ])
315
+ data .val = getBaseValue (data .alphabet , data . input [data .index ])
282
316
data .index += 1
283
317
}
284
318
if respB > 0 {
@@ -302,11 +336,11 @@ func getString(last string, data *dataStruct) (string, bool, error) {
302
336
c := readBits (data .numBits , data )
303
337
switch c {
304
338
case 0 :
305
- str := string (readBits (8 , data ))
339
+ str := string (rune ( readBits (8 , data ) ))
306
340
appendValue (data , str )
307
341
return str , false , nil
308
342
case 1 :
309
- str := string (readBits (16 , data ))
343
+ str := string (rune ( readBits (16 , data ) ))
310
344
appendValue (data , str )
311
345
return str , false , nil
312
346
case 2 :
@@ -327,9 +361,11 @@ func concatWithFirstRune(str string, getFirstRune string) string {
327
361
return str + string (r )
328
362
}
329
363
330
- func DecompressFromBase64 (input string ) (string , error ) {
331
- data := dataStruct {input , getBaseValue (input [0 ]), 32 , 1 , []string {"0" , "1" , "2" }, 5 , 2 }
332
-
364
+ func Decompress (input string , keyStrBase64 string ) (string , error ) {
365
+ if keyStrBase64 == "" {
366
+ keyStrBase64 = _defaultKeyStrBase64
367
+ }
368
+ data := dataStruct {input , keyStrBase64 , getBaseValue (keyStrBase64 , input [0 ]), 32 , 1 , []string {"0" , "1" , "2" }, 5 , 2 }
333
369
result , isEnd , err := getString ("" , & data )
334
370
if err != nil || isEnd {
335
371
return result , err
@@ -341,9 +377,28 @@ func DecompressFromBase64(input string) (string, error) {
341
377
if err != nil || isEnd {
342
378
return result , err
343
379
}
344
-
345
380
result = result + str
346
381
appendValue (& data , concatWithFirstRune (last , str ))
347
382
last = str
348
383
}
349
384
}
385
+
386
+ //func DecompressFromBase64New(input string) (string, error) {
387
+ // data := dataStruct{input, getBaseValue(input[0]), 32, 1, []string{"0", "1", "2"}, 5, 2}
388
+ // result, isEnd, err := getString("", &data)
389
+ // if err != nil || isEnd {
390
+ // return result, err
391
+ // }
392
+ // last := result
393
+ // data.numBits += 1
394
+ // newResBuf := strings.Builder{}
395
+ // for {
396
+ // str, isEnd, err := getString(last, &data)
397
+ // if err != nil || isEnd {
398
+ // return newResBuf.String(), err
399
+ // }
400
+ // newResBuf.WriteString(str)
401
+ // appendValue(&data, concatWithFirstRune(last, str))
402
+ // last = str
403
+ // }
404
+ //}
0 commit comments