id_pack 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,579 @@
1
+ module IdPack
2
+ module LZString
3
+ KEY_STR_BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
4
+ KEY_STR_URI_SAFE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$"
5
+
6
+ class << self
7
+
8
+ def get_base_value alphabet, character
9
+ @base_reverse_dic ||= {}
10
+
11
+ if !@base_reverse_dic[alphabet]
12
+ @base_reverse_dic[alphabet] = {}
13
+
14
+ alphabet.length.times do |i|
15
+ @base_reverse_dic[alphabet][alphabet[i]] = i
16
+ end
17
+ end
18
+
19
+ @base_reverse_dic[alphabet][character]
20
+ end
21
+
22
+ def compress_to_base64 input
23
+ return "" if input.nil?
24
+
25
+ res = _compress(input, 6) do |a|
26
+ KEY_STR_BASE64[a]
27
+ end
28
+
29
+ case res.length % 4
30
+ when 0 then res
31
+ when 1 then res + "==="
32
+ when 2 then res + "=="
33
+ when 3 then res + "="
34
+ end
35
+ end
36
+
37
+ def decompress_from_base64 input
38
+ return "" if input.nil?
39
+ return nil if input == ""
40
+
41
+ _decompress(input.length, 32) do |index|
42
+ get_base_value(KEY_STR_BASE64, input[index])
43
+ end
44
+ end
45
+
46
+ def compress_to_utf16 input
47
+ return "" if input.nil?
48
+
49
+ _compress(input, 15) do |a|
50
+ [a + 32].pack 'U'
51
+ end + " "
52
+ end
53
+
54
+ def decompress_from_utf16 compressed
55
+ return "" if compressed.nil?
56
+ return nil if compressed == ""
57
+
58
+ _decompress(compressed.length, 16384) do |index|
59
+ compressed[index].ord - 32
60
+ end
61
+ end
62
+
63
+ def compress_to_uint8_array uncompressed
64
+ compressed = compress(uncompressed)
65
+ buf = []
66
+
67
+ compressed.length.times do |i|
68
+ current_value = compressed[i].ord
69
+ buf[i * 2] = current_value >> 8 # TODO: >>> 8 how to do it in ruby?
70
+ buf[i * 2 + 1] = current_value % 256
71
+ end
72
+
73
+ buf
74
+ end
75
+
76
+ def decompress_from_uint8_array compressed
77
+ return decompress(compressed) if compressed.nil?
78
+
79
+ buf = []
80
+
81
+ (compressed.length / 2).times do |i|
82
+ buf[i] = compressed[i * 2] * 256 + compressed[i * 2 + 1]
83
+ end
84
+
85
+ result = []
86
+
87
+ buf.each do |c|
88
+ result.push(
89
+ [a + 32].pack 'U'
90
+ )
91
+ end
92
+
93
+ decompress(result.join(''))
94
+ end
95
+
96
+ def compress_to_encoded_uri_component input
97
+ return "" if input.nil?
98
+
99
+ _compress(input, 6) do |a|
100
+ KEY_STR_URI_SAFE[a]
101
+ end
102
+ end
103
+
104
+ def decompress_from_encoded_uri_component input
105
+ return "" if input.nil?
106
+ return nil if input == ""
107
+
108
+ input.gsub!(/ /, "+")
109
+
110
+ _decompress(input.length, 32) do |index|
111
+ get_base_value(KEY_STR_URI_SAFE, input[index])
112
+ end
113
+ end
114
+
115
+ def compress uncompressed
116
+ _compress(uncompressed, 16) do |a|
117
+ [a].pack 'U'
118
+ end
119
+ end
120
+
121
+ def _compress uncompressed, bits_per_char, &get_char_from_int
122
+ return "" if uncompressed.nil?
123
+
124
+ context_dictionary = {}
125
+ context_dictionary_to_create = {}
126
+ context_c = ""
127
+ context_wc = ""
128
+ context_w = ""
129
+ context_enlarge_in = 2
130
+ context_dict_size = 3
131
+ context_num_bits = 2
132
+ context_data = []
133
+ context_data_val = 0
134
+ context_data_position = 0
135
+
136
+ uncompressed.length.times do |ii|
137
+ context_c = uncompressed[ii]
138
+
139
+ if !context_dictionary[context_c]
140
+ context_dictionary[context_c] = context_dict_size
141
+ context_dict_size += 1
142
+ context_dictionary_to_create[context_c] = true
143
+ end
144
+
145
+ context_wc = context_w + context_c
146
+
147
+ if context_dictionary[context_wc]
148
+ context_w = context_wc
149
+ else
150
+ if context_dictionary_to_create[context_w]
151
+ if context_w[0].ord < 256
152
+ context_num_bits.times do |i|
153
+ context_data_val = (context_data_val << 1)
154
+
155
+ if context_data_position == bits_per_char - 1
156
+ context_data_position = 0
157
+ context_data.push(get_char_from_int.call(context_data_val))
158
+ context_data_val = 0
159
+ else
160
+ context_data_position += 1
161
+ end
162
+ end
163
+
164
+ value = context_w[0].ord
165
+
166
+ 8.times do |i|
167
+ context_data_val = (context_data_val << 1) | (value & 1)
168
+
169
+ if context_data_position == bits_per_char - 1
170
+ context_data_position = 0
171
+ context_data.push(get_char_from_int.call(context_data_val))
172
+ context_data_val = 0
173
+ else
174
+ context_data_position += 1
175
+ end
176
+
177
+ value = value >> 1
178
+ end
179
+ else
180
+ value = 1
181
+
182
+ context_num_bits.times do |i|
183
+ context_data_val = (context_data_val << 1) | value
184
+
185
+ if context_data_position == bits_per_char - 1
186
+ context_data_position = 0
187
+ context_data.push(get_char_from_int.call(context_data_val))
188
+ context_data_val = 0
189
+ else
190
+ context_data_position += 1
191
+ end
192
+
193
+ value = 0
194
+ end
195
+
196
+ value = context_w[0].ord
197
+
198
+ 16.times do |i|
199
+ context_data_val = (context_data_val << 1) | (value & 1)
200
+
201
+ if context_data_position == bits_per_char - 1
202
+ context_data_position = 0
203
+ context_data.push(get_char_from_int.call(context_data_val))
204
+ context_data_val = 0
205
+ else
206
+ context_data_position += 1
207
+ end
208
+
209
+ value = value >> 1
210
+ end
211
+ end
212
+
213
+ context_enlarge_in -= 1
214
+
215
+ if context_enlarge_in == 0
216
+ context_enlarge_in = 2 ** context_num_bits
217
+ context_num_bits += 1
218
+ end
219
+
220
+ context_dictionary_to_create.delete(context_w)
221
+ else
222
+ value = context_dictionary[context_w]
223
+
224
+ context_num_bits.times do |i|
225
+ context_data_val = (context_data_val << 1) | (value & 1)
226
+
227
+ if context_data_position == bits_per_char - 1
228
+ context_data_position = 0
229
+ context_data.push(get_char_from_int.call(context_data_val))
230
+ context_data_val = 0
231
+ else
232
+ context_data_position += 1
233
+ end
234
+
235
+ value = value >> 1
236
+ end
237
+ end
238
+
239
+ context_enlarge_in -= 1
240
+
241
+ if context_enlarge_in == 0
242
+ context_enlarge_in = 2 ** context_num_bits
243
+ context_num_bits += 1
244
+ end
245
+
246
+ context_dictionary[context_wc] = context_dict_size
247
+ context_dict_size += 1
248
+ context_w = context_c.to_s
249
+ end
250
+ end
251
+
252
+ if context_w != ""
253
+ if context_dictionary_to_create[context_w]
254
+ if context_w[0].ord < 256
255
+ context_num_bits.times do |i|
256
+ context_data_val = context_data_val << 1
257
+
258
+ if context_data_position == bits_per_char - 1
259
+ context_data_position = 0
260
+ context_data.push(get_char_from_int.call(context_data_val))
261
+ context_data_val = 0
262
+ else
263
+ context_data_position += 1
264
+ end
265
+ end
266
+
267
+ value = context_w[0].ord
268
+
269
+ 8.times do |i|
270
+ context_data_val = (context_data_val << 1) | (value & 1)
271
+
272
+ if context_data_position == bits_per_char - 1
273
+ context_data_position = 0
274
+ context_data.push(get_char_from_int.call(context_data_val))
275
+ context_data_val = 0
276
+ else
277
+ context_data_position += 1
278
+ end
279
+
280
+ value = value >> 1
281
+ end
282
+ else
283
+ value = 1
284
+
285
+ context_num_bits.times do |i|
286
+ context_data_val = (context_data_val << 1) | value
287
+
288
+ if context_data_position == bits_per_char - 1
289
+ context_data_position = 0
290
+ context_data.push(get_char_from_int.call(context_data_val))
291
+ context_data_val = 0
292
+ else
293
+ context_data_position += 1
294
+ end
295
+
296
+ value = 0
297
+ end
298
+
299
+ value = context_w[0].ord
300
+
301
+ 16.times do |i|
302
+ context_data_val = (context_data_val << 1) | (value & 1)
303
+
304
+ if context_data_position == bits_per_char - 1
305
+ context_data_position = 0
306
+ context_data.push(get_char_from_int.call(context_data_val))
307
+ context_data_val = 0
308
+ else
309
+ context_data_position += 1
310
+ end
311
+
312
+ value = value >> 1
313
+ end
314
+ end
315
+
316
+ context_enlarge_in -= 1
317
+
318
+ if context_enlarge_in == 0
319
+ context_enlarge_in = 2 ** context_num_bits
320
+ context_num_bits += 1
321
+ end
322
+
323
+ context_dictionary_to_create.delete(context_w)
324
+ else
325
+ value = context_dictionary[context_w]
326
+
327
+ context_num_bits.times do |i|
328
+ context_data_val = (context_data_val << 1) | (value & 1)
329
+
330
+ if context_data_position == bits_per_char - 1
331
+ context_data_position = 0
332
+ context_data.push(get_char_from_int.call(context_data_val))
333
+ context_data_val = 0
334
+ else
335
+ context_data_position += 1
336
+ end
337
+
338
+ value = value >> 1
339
+ end
340
+ end
341
+
342
+ context_enlarge_in -= 1
343
+
344
+ if context_enlarge_in == 0
345
+ context_enlarge_in = 2 ** context_num_bits
346
+ context_num_bits += 1
347
+ end
348
+ end
349
+
350
+ value = 2
351
+
352
+ context_num_bits.times do |i|
353
+ context_data_val = (context_data_val << 1) | (value & 1)
354
+
355
+ if context_data_position == bits_per_char - 1
356
+ context_data_position = 0
357
+ context_data.push(get_char_from_int.call(context_data_val))
358
+ context_data_val = 0
359
+ else
360
+ context_data_position += 1
361
+ end
362
+
363
+ value = value >> 1
364
+ end
365
+
366
+ while true do
367
+ context_data_val = (context_data_val << 1)
368
+
369
+ if context_data_position == bits_per_char - 1
370
+ context_data.push(get_char_from_int.call(context_data_val))
371
+ break
372
+ else
373
+ context_data_position += 1
374
+ end
375
+ end
376
+
377
+ context_data.join('')
378
+ end
379
+
380
+ def decompress compressed
381
+ return "" if compressed.nil?
382
+ return null if compressed == ""
383
+
384
+ _decompress(compressed.length, 32768) do |index|
385
+ compressed[index].ord
386
+ end
387
+ end
388
+
389
+ def _decompress length, reset_value, &get_next_value
390
+ dictionary = []
391
+ enlarge_in = 4
392
+ dict_size = 4
393
+ num_bits = 3
394
+ entry = ""
395
+ result = []
396
+ data = {
397
+ val: get_next_value.call(0),
398
+ position: reset_value,
399
+ index: 1
400
+ }
401
+
402
+ 3.times do |i|
403
+ dictionary[i] = i
404
+ end
405
+
406
+ bits = 0
407
+ maxpower = 2 ** 2
408
+ power = 1
409
+
410
+ while power != maxpower
411
+ resb = data[:val] & data[:position]
412
+ data[:position] = data[:position] >> 1
413
+
414
+ if data[:position] == 0
415
+ data[:position] = reset_value
416
+ data[:val] = get_next_value.call(data[:index])
417
+ data[:index] += 1
418
+ end
419
+
420
+ bits |= (resb > 0 ? 1 : 0) * power
421
+ power = power << 1
422
+ end
423
+
424
+ case bits
425
+ when 0
426
+ bits = 0
427
+ maxpower = 2 ** 8
428
+ power = 1
429
+
430
+ while power != maxpower
431
+ resb = data[:val] & data[:position]
432
+ data[:position] = data[:position] >> 1
433
+
434
+ if data[:position] == 0
435
+ data[:position] = reset_value
436
+ data[:val] = get_next_value.call(data[:index])
437
+ data[:index] += 1
438
+ end
439
+
440
+ bits |= (resb > 0 ? 1 : 0) * power
441
+ power <<= 1
442
+ end
443
+
444
+ c = [bits].pack 'U'
445
+ when 1
446
+ bits = 0
447
+ maxpower = 2 ** 16
448
+ power = 1
449
+
450
+ while power != maxpower
451
+ resb = data[:val] & data[:position]
452
+ data[:position] = data[:position] >> 1
453
+
454
+ if data[:position] == 0
455
+ data[:position] = reset_value
456
+ data[:val] = get_next_value.call(data[:index])
457
+ data[:index] += 1
458
+ end
459
+
460
+ bits |= (resb > 0 ? 1 : 0) * power
461
+ power <<= 1
462
+ end
463
+
464
+ c = [bits].pack 'U'
465
+ when 2
466
+ return ""
467
+ end
468
+
469
+ dictionary[3] = c
470
+ w = c
471
+ result.push(c)
472
+
473
+ while true do
474
+ return "" if data[:index] > length
475
+
476
+ bits = 0
477
+ maxpower = 2 ** num_bits
478
+ power = 1
479
+
480
+ while power != maxpower
481
+ resb = data[:val] & data[:position]
482
+ data[:position] = data[:position] >> 1
483
+
484
+ if data[:position] == 0
485
+ data[:position] = reset_value
486
+ data[:val] = get_next_value.call(data[:index])
487
+ data[:index] += 1
488
+ end
489
+
490
+ bits |= (resb > 0 ? 1 : 0) * power
491
+ power <<= 1
492
+ end
493
+
494
+ c = bits
495
+
496
+ case bits
497
+ when 0
498
+ bits = 0
499
+ maxpower = 2 ** 8
500
+ power = 1
501
+
502
+ while power != maxpower
503
+ resb = data[:val] & data[:position]
504
+ data[:position] >>= 1
505
+
506
+ if data[:position] == 0
507
+ data[:position] = reset_value
508
+ data[:val] = get_next_value.call(data[:index])
509
+ data[:index] += 1
510
+ end
511
+
512
+ bits |= (resb > 0 ? 1 : 0) * power
513
+ power <<= 1
514
+ end
515
+
516
+ dictionary[dict_size] = [bits].pack 'U'
517
+ dict_size += 1
518
+ c = dict_size - 1
519
+ enlarge_in -= 1
520
+ when 1
521
+ bits = 0
522
+ maxpower = 2 ** 16
523
+ power = 1
524
+
525
+ while power != maxpower
526
+ resb = data[:val] & data[:position]
527
+ data[:position] >>= 1
528
+
529
+ if data[:position] == 0
530
+ data[:position] = reset_value
531
+ data[:val] = get_next_value.call(data[:index])
532
+ data[:index] += 1
533
+ end
534
+
535
+ bits |= (resb > 0 ? 1 : 0) * power
536
+ power <<= 1
537
+ end
538
+
539
+ dictionary[dict_size] = [bits].pack 'U'
540
+ dict_size += 1
541
+ c = dict_size - 1
542
+ enlarge_in -= 1
543
+ when 2
544
+ return result.join("")
545
+ end
546
+
547
+ if enlarge_in == 0
548
+ enlarge_in = 2 ** num_bits
549
+ num_bits += 1
550
+ end
551
+
552
+ if dictionary[c]
553
+ entry = dictionary[c]
554
+ else
555
+ return nil if c != dict_size
556
+
557
+ entry = w + w[0]
558
+ end
559
+
560
+ result.push(entry)
561
+
562
+ dictionary[dict_size] = w + entry[0]
563
+ dict_size += 1
564
+ enlarge_in -= 1
565
+
566
+ w = entry
567
+
568
+ if enlarge_in == 0
569
+ enlarge_in = 2 ** num_bits
570
+ num_bits += 1
571
+ end
572
+ end
573
+ end
574
+
575
+ end
576
+
577
+ end
578
+
579
+ end