我正在编写一个与流行的数据仓库SaaS交互的工具。他们的在线sql编辑器将sql工作表序列化为JSON,但sql工作表的主体使用pako.js进行了zlib压缩。 我试图从python中读取并扩展这些zlib字符串,但我只能对包含短字符串的ByTestRing进行解码
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 magic number,它可以解压这些字符串,而不需要去掉页眉和页脚,但是当从-64循环到64时,我无法得到任何组合
我中断了联机sql工作表编辑器的保存和加载函数,发现它们使用的是pako zlib库pako.deflate(a, {to: 'string'})
和pako.inflate(b['body'], {to: 'string'})
,我可以使用pako
库在浏览器中膨胀/收缩sql字符串,但无法在python中再现相同的结果
\xef\xbf\xbd
的每个序列表示原始数据的损坏实例在第一个示例中,第一个也是唯一的
\xef\xbf\xbd
应该是一个单字节,它是zlib头的第二个字节。在第二个示例中,第一个\xef\xbf\xbd
应该是zlib头的第二个字节,第二个实例应该是\b4
,第三个实例应该是\ff
,第四个实例应该是\9b
在这条路上的某个地方有一些UTF-8处理不应该发生。每当它遇到一个设置了高位的字节时,它就会失败。在这些情况下,它用三字节UTF-8序列
U+FFFD
替换字节,这是用于表示未知字符的“替换”字符归根结底,您的数据已损坏,无法修复。你需要修复上游发生的一切。您是否正在尝试使用复制和粘贴来获取数据?如果你在黑钻石上看到一个问号,那就是UTF-8字符
我同意这是一个数据损坏问题
zlib
和pako
应该能够读取彼此的数据,而无需删除任何字段或添加幻数为了证明这一点,我收集了两个演示脚本,一个使用
pako
压缩数据,另一个使用zlib
再次压缩数据:使用
node deflate.js "Here is some example text" | inflate.py
在命令行上运行它们。预期的输出是传递给node deflate.js
的参数关于
pako
值得指出的一点是使用to: "string"
选项时的行为。此选项的documentation如下所示:正是出于这个原因,我在上面的JavaScript函数中使用了
escape
。使用escape
可以确保JavaScript和Python之间传递的字符串不包含任何非ASCII字符。(请注意,encodeURIComponent
不工作,因为字符串包含二进制数据。)然后我在Python中使用urllib.parse.unquote_to_bytes
来撤消此转义如果您可以在浏览器中
escape
压缩pako
的数据,那么您可能会将其传递给Python以再次对其进行膨胀相关问题 更多 >
编程相关推荐