Last active
October 10, 2018 23:20
-
-
Save feilongfl/13e9b5b44eadc4b1917b596de5934bbe to your computer and use it in GitHub Desktop.
ebb-json-decoder
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#/usr/bin/env python | |
# written by https://github.com/v-python | |
def decompress(compressed): | |
if (compressed is None) or (compressed == ''): | |
return '' | |
dictionary = {} | |
enlargeIn = 4 | |
dictSize = 4 | |
numBits = 3 | |
(entry, result, w, c) = ('', '', '', '') | |
(i, nnext, bits, resb, maxpower, power) = (0, 0, 0, 0, 0, 0) | |
data_string = compressed | |
data_val = ord(compressed[0]) | |
data_position = 32768 | |
data_index = 1 | |
for i in range(3): | |
# dictionary[i] = i | |
dictionary[i] = '' | |
bits = 0 | |
maxpower = pow(2, 2) | |
power = 1 | |
while power != maxpower: | |
resb = data_val & data_position | |
data_position >>= 1 | |
if data_position == 0: | |
data_position = 32768 | |
data_val = ord(data_string[data_index]) | |
data_index += 1 | |
bits |= (1 if resb > 0 else 0) * power | |
power <<= 1 | |
nnext = bits | |
if nnext == 0: | |
bits = 0 | |
maxpower = pow(2, 8) | |
power = 1 | |
while power != maxpower: | |
resb = data_val & data_position | |
data_position >>= 1 | |
if data_position == 0: | |
data_position = 32768 | |
data_val = ord(data_string[data_index]) | |
data_index += 1 | |
bits |= (1 if resb > 0 else 0) * power | |
power <<= 1 | |
c = chr(bits) | |
elif nnext == 1: | |
bits = 0 | |
maxpower = pow(2, 16) | |
power = 1 | |
while power != maxpower: | |
resb = data_val & data_position | |
data_position >>= 1 | |
if data_position == 0: | |
data_position = 32768 | |
data_val = ord(data_string[data_index]) | |
data_index += 1 | |
bits |= (1 if resb > 0 else 0) * power | |
power <<= 1 | |
c = chr(bits) | |
elif nnext == 2: | |
return '' | |
dictionary[3] = c | |
result = c | |
w = result | |
while True: | |
if data_index > len(data_string): | |
return '' | |
bits = 0 | |
maxpower = pow(2, numBits) | |
power = 1 | |
while power != maxpower: | |
resb = data_val & data_position | |
data_position >>= 1 | |
if data_position == 0: | |
data_position = 32768 | |
data_val = ord(data_string[data_index]) | |
data_index += 1 | |
bits |= (1 if resb > 0 else 0) * power | |
power <<= 1 | |
c = bits | |
if c == 0: | |
bits = 0 | |
maxpower = pow(2, 8) | |
power = 1 | |
while power != maxpower: | |
resb = data_val & data_position | |
data_position >>= 1 | |
if data_position == 0: | |
data_position = 32768 | |
data_val = ord(data_string[data_index]) | |
data_index += 1 | |
bits |= (1 if resb > 0 else 0) * power | |
power <<= 1 | |
dictionary[dictSize] = chr(bits) | |
dictSize += 1 | |
c = dictSize - 1 | |
enlargeIn -= 1 | |
elif c == 1: | |
bits = 0 | |
maxpower = pow(2, 16) | |
power = 1 | |
while power != maxpower: | |
resb = data_val & data_position | |
data_position >>= 1 | |
if data_position == 0: | |
data_position = 32768 | |
data_val = ord(data_string[data_index]) | |
data_index += 1 | |
bits |= (1 if resb > 0 else 0) * power | |
power <<= 1 | |
dictionary[dictSize] = chr(bits) | |
dictSize += 1 | |
c = dictSize - 1 | |
enlargeIn -= 1 | |
elif c == 2: | |
return result | |
if enlargeIn == 0: | |
enlargeIn = pow(2, numBits) | |
numBits += 1 | |
if c in dictionary: | |
entry = dictionary[c] | |
else: | |
if c == dictSize: | |
entry = w + w[0] | |
else: | |
return None | |
result += entry | |
dictionary[dictSize] = w + entry[0] | |
dictSize += 1 | |
enlargeIn -= 1 | |
w = entry | |
if enlargeIn == 0: | |
enlargeIn = pow(2, numBits) | |
numBits += 1 | |
def decompressFromUTF16(string): | |
if not string: | |
return "" | |
output = "" | |
status = 0 | |
for i, k in enumerate(string): | |
c = ord(k) - 32 | |
if status == 0: | |
status = 1 | |
current = c << 1 | |
elif status == 1: | |
status = 2 | |
output += chr(current + (c >> 14)) | |
current = (c & 16383) << 2 | |
elif status == 2: | |
status = 3 | |
output += chr(current + (c >> 13)) | |
current = (c & 8191) << 3 | |
elif status == 3: | |
status = 4 | |
output += chr(current + (c >> 12)) | |
current = (c & 4095) << 4 | |
elif status == 4: | |
status = 5 | |
output += chr(current + (c >> 11)) | |
current = (c & 2047) << 5 | |
elif status == 5: | |
status = 6 | |
output += chr(current + (c >> 10)) | |
current = (c & 1023) << 6 | |
elif status == 6: | |
status = 7 | |
output += chr(current + (c >> 9)) | |
current = (c & 511) << 7 | |
elif status == 7: | |
status = 8 | |
output += chr(current + (c >> 8)) | |
current = (c & 255) << 8 | |
elif status == 8: | |
status = 9 | |
output += chr(current + (c >> 7)) | |
current = (c & 127) << 9 | |
elif status == 9: | |
status = 10 | |
output += chr(current + (c >> 6)) | |
current = (c & 63) << 10 | |
elif status == 10: | |
status = 11 | |
output += chr(current + (c >> 5)) | |
current = (c & 31) << 11 | |
elif status == 11: | |
status = 12 | |
output += chr(current + (c >> 4)) | |
current = (c & 15) << 12 | |
elif status == 12: | |
status = 13 | |
output += chr(current + (c >> 3)) | |
current = (c & 7) << 13 | |
elif status == 13: | |
status = 14 | |
output += chr(current + (c >> 2)) | |
current = (c & 3) << 14 | |
elif status == 14: | |
status = 15 | |
output += chr(current + (c >> 1)) | |
current = (c & 1) << 15 | |
elif status == 15: | |
status = 0 | |
output += chr(current + c) | |
current = (c & 1) << 15 | |
return decompress(output) | |
# test | |
f = open('anime_list', 'r') | |
r = decompressFromUTF16(f.read()) | |
print(r) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
var f = String.fromCharCode; | |
decompressFromUTF16 = function(compressed) { | |
if (compressed == null) return ""; | |
if (compressed == "") return null; | |
return _decompress(compressed.length, 16384, function(index) { | |
return compressed.charCodeAt(index) - 32; | |
}); | |
} | |
_decompress = function(length, resetValue, getNextValue) { | |
var dictionary = [], | |
next, | |
enlargeIn = 4, | |
dictSize = 4, | |
numBits = 3, | |
entry = "", | |
result = [], | |
i, | |
w, | |
bits, resb, maxpower, power, | |
c, | |
data = { | |
val: getNextValue(0), | |
position: resetValue, | |
index: 1 | |
}; | |
for (i = 0; i < 3; i += 1) { | |
dictionary[i] = i; | |
} | |
bits = 0; | |
maxpower = Math.pow(2, 2); | |
power = 1; | |
while (power != maxpower) { | |
resb = data.val & data.position; | |
data.position >>= 1; | |
if (data.position == 0) { | |
data.position = resetValue; | |
data.val = getNextValue(data.index++); | |
} | |
bits |= (resb > 0 ? 1 : 0) * power; | |
power <<= 1; | |
} | |
switch (next = bits) { | |
case 0: | |
bits = 0; | |
maxpower = Math.pow(2, 8); | |
power = 1; | |
while (power != maxpower) { | |
resb = data.val & data.position; | |
data.position >>= 1; | |
if (data.position == 0) { | |
data.position = resetValue; | |
data.val = getNextValue(data.index++); | |
} | |
bits |= (resb > 0 ? 1 : 0) * power; | |
power <<= 1; | |
} | |
c = f(bits); | |
break; | |
case 1: | |
bits = 0; | |
maxpower = Math.pow(2, 16); | |
power = 1; | |
while (power != maxpower) { | |
resb = data.val & data.position; | |
data.position >>= 1; | |
if (data.position == 0) { | |
data.position = resetValue; | |
data.val = getNextValue(data.index++); | |
} | |
bits |= (resb > 0 ? 1 : 0) * power; | |
power <<= 1; | |
} | |
c = f(bits); | |
break; | |
case 2: | |
return ""; | |
} | |
dictionary[3] = c; | |
w = c; | |
result.push(c); | |
while (true) { | |
if (data.index > length) { | |
return ""; | |
} | |
bits = 0; | |
maxpower = Math.pow(2, numBits); | |
power = 1; | |
while (power != maxpower) { | |
resb = data.val & data.position; | |
data.position >>= 1; | |
if (data.position == 0) { | |
data.position = resetValue; | |
data.val = getNextValue(data.index++); | |
} | |
bits |= (resb > 0 ? 1 : 0) * power; | |
power <<= 1; | |
} | |
switch (c = bits) { | |
case 0: | |
bits = 0; | |
maxpower = Math.pow(2, 8); | |
power = 1; | |
while (power != maxpower) { | |
resb = data.val & data.position; | |
data.position >>= 1; | |
if (data.position == 0) { | |
data.position = resetValue; | |
data.val = getNextValue(data.index++); | |
} | |
bits |= (resb > 0 ? 1 : 0) * power; | |
power <<= 1; | |
} | |
dictionary[dictSize++] = f(bits); | |
c = dictSize - 1; | |
enlargeIn--; | |
break; | |
case 1: | |
bits = 0; | |
maxpower = Math.pow(2, 16); | |
power = 1; | |
while (power != maxpower) { | |
resb = data.val & data.position; | |
data.position >>= 1; | |
if (data.position == 0) { | |
data.position = resetValue; | |
data.val = getNextValue(data.index++); | |
} | |
bits |= (resb > 0 ? 1 : 0) * power; | |
power <<= 1; | |
} | |
dictionary[dictSize++] = f(bits); | |
c = dictSize - 1; | |
enlargeIn--; | |
break; | |
case 2: | |
return result.join(''); | |
} | |
if (enlargeIn == 0) { | |
enlargeIn = Math.pow(2, numBits); | |
numBits++; | |
} | |
if (dictionary[c]) { | |
entry = dictionary[c]; | |
} else { | |
if (c === dictSize) { | |
entry = w + w.charAt(0); | |
} else { | |
return null; | |
} | |
} | |
result.push(entry); | |
// Add w+entry[0] to the dictionary. | |
dictionary[dictSize++] = w + entry.charAt(0); | |
enlargeIn--; | |
w = entry; | |
if (enlargeIn == 0) { | |
enlargeIn = Math.pow(2, numBits); | |
numBits++; | |
} | |
} | |
} | |
function decode(code) { | |
return JSON.parse(decompressFromUTF16(code)) | |
} | |
var rf = require("fs"); | |
var data = rf.readFileSync("anime_list", "utf-8"); | |
// console.log(data); | |
console.log(JSON.stringify(decode(data))); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
example:
resault: