我正在编写一个与流行的数据仓库 SaaS 交互的工具。他们的在线 sql 编辑器将 sql 工作表序列化为 JSON,但 SQL 工作表的主体是使用 pako.js 对 zlib 进行压缩的。我正在尝试从 python 读取和扩充这些 zlib 字符串,但我只能解码包含短的字节串
带有 sql 文本的示例是字母a
:
bytestring = b'x\xef\xbf\xbdK\x04\x00\x00b\x00b\n'
zlib.decompress(bytestring[4:-4], -15).decode('utf-8')
>>> "a"
如果我包含分号a;
,则无法解压缩:
bytestring = b'x\xef\xbf\xbdK\xef\xbf\xbd\x06\x00\x00\xef\xbf\xbd\x00\xef\xbf\xbd\n'
zlib.decompress(bytestring[4:-4], -15).decode('utf-8')
*** UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8f in position 1: invalid start byte
注意:我还尝试使用 'punycode' 解码这些示例,我在 javascript 实现中找到了参考。
我对 zlib 的理解非常有限,但我发现 zlib 字符串的前两个和最后四个字节是页眉/页脚,如果我们使用幻数 -15 运行 zlib 可以修剪。完全有可能有 zlib 幻数可以解压缩这些字符串而无需剥离页眉和页脚,但是当从 -64 循环到 64 时,我无法让任何组合起作用。
我已经通过在线 sql 工作表编辑器的保存和加载功能设置了断点,发现它们正在使用 pako zlib 库pako.deflate(a, {to: 'string'})
,pako.inflate(b['body'], {to: 'string'})
并且我可以使用该pako
库在浏览器中对 sql 字符串进行充气/放气,但一直无法在 python 中重现相同的结果。