Python 3中字节、十六进制和字符串之间的混淆

2024-05-13 04:15:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个包含十六进制字符串的日志文件。我必须把它转换成一个清晰的句子。但是,我注意到字符串处理过程中出现了一些不稳定的行为

例如,日志文件中最短的一行是

82099fd4e8643133b854c842231e33fe99601adfbb32fe19070dc7b665c27f4510eccdd20c8c68b9ffe6fb941554cb675f92fdfd043a7855f8e5ec1f4b1869595f2ee3e89269d3035c77b3e7d520dc786fecc6074c23565a5de9837627e676676bdbfdeda5d5b52895b2ccdaaa373b5cc8ca7e927d885db6d69fed2175df66b23d21b93b5bdbb619bbde75b39acd42d76778259a4a3653473e74fcd0ec0182401ac5367967c1d8de79cb98fab4bf73b561202042dd94853c0e1375fbd147377de48c7050f660af2f55c572ac53384e3c270c95a20767326f58011139217cef33ae4dd5d94835a1717ad60d478b335d4d78901f51467c0d9e73032f95df834f0105012ae3a9e2b82be5981e340e24b71282b002c512d126c1c6edc868cd13cac190a923cd58e6ec08e48426d1f79969833e4499650e1846c93983efc1364ace994ebf2e12fe41aa0e23214b1f04176ec331967395fd4f3ef374f34dc5ed310748398d87528e3eb0ccde6113151d4cd8634dc755e571a7383a1abdbda4bc9a360c75b444628b5fea075a3ab5ac9d169c565645ed3a14997c3d6e1e62516161986a251ae4c2c3d74c248748d956ffdbaa4dcc6bbd11d2f85f00fdf28cbb0b4bb2143030d0d3b5d0d351756c538785d544c775bbe504089616d32c1903aab5f93e986c2a59dfec2d8e5a380563d3f24be2891835cd5bc6bf73c4803644ee9d5d109c2648e76fab6903a6b8bde98de29c5845b550b7cda83668f1706f5c5388010e200d1954230c4cdf18c824356cfb8c01a1f98493cdd4321195adf0d2cf37951a191429b8b9e5062d5c17fc6d356af5fd34fcfb874a9df39bed83dced182becd09ed1d8be2e853d3b1f1397eeeddcf3bbb91dce6c1bb7b7ddbe7e98bd383efbf0e19254cbf489ae8b6596c0e474376cd8f555b3b8c16e491e86b4195f40f6426967c450dbc9a01dbf2d7d05437017002822cc562096d19455266bfe0c7981818e5e8590555af3ef2e4f39fc70023805095443f5be673be68ed99cd823d82e2b831117377b09ea4375aefb6dac75d2c468264e3d22aa1071aaac220ce1052424e85fc2b52d1b22763b7e5b4a9992f5c67c1d5ead25535cab570ab5c1c9752c39d0a76bd0ffd0bb9bc7e0652edf7014d4da9864619b4d1ed10c2f3c5a3b863e2c8e06a947c831d1f328c8244f1f853c4f2f44ee49eb2ee4251eaebc1a4ef0f0a418fff041f33e9c5d58e904f198bd0e23ab7264a19f3ff1d14b8ee0020f591efb7673bd1ec13d37637c105b442fc2af82b48902b0b22be9086d0cdf3148500c62f72a06994980863f2f0e49c1d6e3a65595c61aa6dbb8d55ce330c617d8a1f3df219347ebec4e2ed4809520208b3af588071e42fdf721c1766bf1461fdad89f00b5dda5d6f538d8e517542bd949b1d6324f625d030b5973f6d0fcfc89242bc1735975c2025e3c40a2102887ad45994734e39b81353e2ea63ae2cae7ecf39a2b6c862762a90dcc8b9bca897874928cb9f7d32cb30c9cd43b2462c636fa26a9e5aa147361584f15f619964b7f8a887c0083e5956dc810d3894c2d228e28d5351210425b2cdbaaf64a702cb6e120130c540e5d29b2cf7fffc0ae7c252d1d09189b52ba82012193527cdf03f8417039dea5028100d5a5ad637ad0e88e91043aa321486e1e7a7a8a78c8ceec015d4c4046f6c75e2d3d53b1b2aec8a4fab6df9654bc93e718d61bdc307a7e7b6feea27b0d03a460f8bf2538d838e48178d649b1e4c76dbbc0c6d63aa35a9827d7fd109a763eadb217a5ec6362e5bfb5a35048b11bed20c3da738bb5385895667014babf04842b983f1272d9d675fa407b2cbb6224f2cad2a3bdfb51c0de8809d69b63e48315c0f31e51cd2a555ac9781b5e40d787a1ea297a78b3d7cc0ad0d907b28940c3c9819d156b869507c1cf3c982e17

我使用以下代码段将其转换为字节对象

binascii.unhexlify(line[:-1])

使用[:-1]删除结尾处的结束行字符

我得到一个字节对象,如下所示

b'\x82\t\x9f\xd4\xe8d13\xb8T\xc8B#\x1e3\xfe\x99`\x1a\xdf\xbb2\xfe\x19\x07\r\xc7\xb6e\xc2\x7fE\x10\xec\xcd\xd2\x0c\x8ch\xb9\xff\xe6\xfb\x94\x15T\xcbg_\x92\xfd\xfd\x04:xU\xf8\xe5\xec\x1fK\x18iY_.\xe3\xe8\x92i\xd3\x03\\w\xb3\xe7\xd5 \xdcxo\xec\xc6\x07L#VZ]\xe9\x83v\'\xe6vgk\xdb\xfd\xed\xa5\xd5\xb5(\x95\xb2\xcc\xda\xaa7;\\\xc8\xca~\x92}\x88]\xb6\xd6\x9f\xed!u\xdff\xb2=!\xb9;[\xdb\xb6\x19\xbb\xdeu\xb3\x9a\xcdB\xd7gx%\x9aJ6SG>t\xfc\xd0\xec\x01\x82@\x1a\xc56yg\xc1\xd8\xdey\xcb\x98\xfa\xb4\xbfs\xb5a  B\xdd\x94\x85<\x0e\x13u\xfb\xd1G7}\xe4\x8cpP\xf6`\xaf/U\xc5r\xacS8N<\'\x0c\x95\xa2\x07g2oX\x01\x119!|\xef3\xaeM\xd5\xd9H5\xa1qz\xd6\rG\x8b3]Mx\x90\x1fQF|\r\x9es\x03/\x95\xdf\x83O\x01\x05\x01*\xe3\xa9\xe2\xb8+\xe5\x98\x1e4\x0e$\xb7\x12\x82\xb0\x02\xc5\x12\xd1&\xc1\xc6\xed\xc8h\xcd\x13\xca\xc1\x90\xa9#\xcdX\xe6\xec\x08\xe4\x84&\xd1\xf7\x99i\x83>D\x99e\x0e\x18F\xc99\x83\xef\xc16J\xce\x99N\xbf.\x12\xfeA\xaa\x0e#!K\x1f\x04\x17n\xc31\x96s\x95\xfdO>\xf3t\xf3M\xc5\xed1\x07H9\x8d\x87R\x8e>\xb0\xcc\xdea\x13\x15\x1dL\xd8cM\xc7U\xe5q\xa78:\x1a\xbd\xbd\xa4\xbc\x9a6\x0cu\xb4Db\x8b_\xea\x07Z:\xb5\xac\x9d\x16\x9cVVE\xed:\x14\x99|=n\x1ebQaa\x98j%\x1a\xe4\xc2\xc3\xd7L$\x87H\xd9V\xff\xdb\xaaM\xcck\xbd\x11\xd2\xf8_\x00\xfd\xf2\x8c\xbb\x0bK\xb2\x1400\xd0\xd3\xb5\xd0\xd3QulS\x87\x85\xd5D\xc7u\xbb\xe5\x04\x08\x96\x16\xd3,\x19\x03\xaa\xb5\xf9>\x98l*Y\xdf\xec-\x8eZ8\x05c\xd3\xf2K\xe2\x89\x185\xcd[\xc6\xbfs\xc4\x806D\xee\x9d]\x10\x9c&H\xe7o\xabi\x03\xa6\xb8\xbd\xe9\x8d\xe2\x9cXE\xb5P\xb7\xcd\xa86h\xf1po\\S\x88\x01\x0e \r\x19T#\x0cL\xdf\x18\xc8$5l\xfb\x8c\x01\xa1\xf9\x84\x93\xcd\xd42\x11\x95\xad\xf0\xd2\xcf7\x95\x1a\x19\x14)\xb8\xb9\xe5\x06-\\\x17\xfcm5j\xf5\xfd4\xfc\xfb\x87J\x9d\xf3\x9b\xed\x83\xdc\xed\x18+\xec\xd0\x9e\xd1\xd8\xbe.\x85=;\x1f\x13\x97\xee\xed\xdc\xf3\xbb\xb9\x1d\xcel\x1b\xb7\xb7\xdd\xbe~\x98\xbd8>\xfb\xf0\xe1\x92T\xcb\xf4\x89\xae\x8be\x96\xc0\xe4t7l\xd8\xf5U\xb3\xb8\xc1nI\x1e\x86\xb4\x19_@\xf6Big\xc4P\xdb\xc9\xa0\x1d\xbf-}\x05Cp\x17\x00("\xccV \x96\xd1\x94U&k\xfe\x0cy\x81\x81\x8e^\x85\x90UZ\xf3\xef.O9\xfcp\x028\x05\tTC\xf5\xbeg;\xe6\x8e\xd9\x9c\xd8#\xd8.+\x83\x11\x177{\t\xeaCu\xae\xfbm\xacu\xd2\xc4h&N="\xaa\x10q\xaa\xac"\x0c\xe1\x05$$\xe8_\xc2\xb5-\x1b"v;~[J\x99\x92\xf5\xc6|\x1d^\xad%S\\\xabW\n\xb5\xc1\xc9u,9\xd0\xa7k\xd0\xff\xd0\xbb\x9b\xc7\xe0e.\xdfp\x14\xd4\xda\x98da\x9bM\x1e\xd1\x0c/<Z;\x86>,\x8e\x06\xa9G\xc81\xd1\xf3(\xc8$O\x1f\x85<O/D\xeeI\xeb.\xe4%\x1e\xae\xbc\x1aN\xf0\xf0\xa4\x18\xff\xf0A\xf3>\x9c]X\xe9\x04\xf1\x98\xbd\x0e#\xabrd\xa1\x9f?\xf1\xd1K\x8e\xe0\x02\x0fY\x1e\xfbvs\xbd\x1e\xc1=7c|\x10[D/\xc2\xaf\x82\xb4\x89\x02\xb0\xb2+\xe9\x08m\x0c\xdf1HP\x0cb\xf7*\x06\x99I\x80\x86?/\x0eI\xc1\xd6\xe3\xa6U\x95\xc6\x1a\xa6\xdb\xb8\xd5\\\xe30\xc6\x17\xd8\xa1\xf3\xdf!\x93G\xeb\xecN.\xd4\x80\x95  \x8b:\xf5\x88\x07\x1eB\xfd\xf7!\xc1vk\xf1F\x1f\xda\xd8\x9f\x00\xb5\xdd\xa5\xd6\xf58\xd8\xe5\x17T+\xd9I\xb1\xd62Ob]\x03\x0bYs\xf6\xd0\xfc\xfc\x89$+\xc1sYu\xc2\x02^<@\xa2\x10(\x87\xadE\x99G4\xe3\x9b\x815>.\xa6:\xe2\xca\xe7\xec\xf3\x9a+l\x86\'b\xa9\r\xcc\x8b\x9b\xca\x89xt\x92\x8c\xb9\xf7\xd3,\xb3\x0c\x9c\xd4;$b\xc66\xfa&\xa9\xe5\xaa\x14saXO\x15\xf6\x19\x96K\x7f\x8a\x88|\x00\x83\xe5\x95m\xc8\x10\xd3\x89L-"\x8e(\xd55\x12\x10B[,\xdb\xaa\xf6Jp,\xb6\xe1 \x13\x0cT\x0e])\xb2\xcf\x7f\xff\xc0\xae|%-\x1d\t\x18\x9bR\xba\x82\x01!\x93R|\xdf\x03\xf8Ap9\xde\xa5\x02\x81\x00\xd5\xa5\xadcz\xd0\xe8\x8e\x91\x04:\xa3!Hn\x1ezz\x8ax\xc8\xce\xec\x01]L@F\xf6\xc7^-=S\xb1\xb2\xae\xc8\xa4\xfa\xb6\xdf\x96T\xbc\x93\xe7\x18\xd6\x1b\xdc0z~{o\xee\xa2{\r\x03\xa4`\xf8\xbf%8\xd88\xe4\x81x\xd6I\xb1\xe4\xc7m\xbb\xc0\xc6\xd6:\xa3Z\x98\'\xd7\xfd\x10\x9av>\xad\xb2\x17\xa5\xeccb\xe5\xbf\xb5\xa3PH\xb1\x1b\xed \xc3\xdas\x8b\xb58X\x95fp\x14\xba\xbf\x04\x84+\x98?\x12r\xd9\xd6u\xfa@{,\xbbb$\xf2\xca\xd2\xa3\xbd\xfbQ\xc0\xde\x88\t\xd6\x9bc\xe4\x83\x15\xc0\xf3\x1eQ\xcd*UZ\xc9x\x1b^@\xd7\x87\xa1\xea)zx\xb3\xd7\xcc\n\xd0\xd9\x07\xb2\x89@\xc3\xc9\x81\x9d\x15k\x86\x95\x07\xc1\xcf<\x98.\x17'

现在,我的理解是,这些是十六进制代码,可能会有一个“解码”版本。 现在,出于某种原因,我复制了字符串的一部分,将其分配给一个变量,然后正常地打印它,它给出了一个“解码”版本(虽然这是随机的胡言乱语,但它可以工作)

print('\x98l*Y\xdf\xec-\x8eZ8\x05c\xd3\xf2K\xe2\x89\x185\xcd[\xc6\xbfs\xc4\x806D\xee\x9d]\x10\x9c&H\xe7o\xabi\x03\xa6\xb8\xbd\xe9\x8d\xe2\x9cXE\xb5P\xb7\xcd\xa86h\xf1po\\S\x88\x01\x0e \r\x19T#\x0cL\xdf\x18\xc8$5l\xfb\x8c\x01\xa1\xf9\x84\x93\xcd\xd42\x11\x95\xad\xf0\xd2\xcf7\x95\x1a\x19\x14)\xb8\xb9\xe5\x06-\\\x17\xfcm5j\xf5\xfd4\xfc\xfb\x87J\x9d\xf3\x9b\xed\x83\xdc\xed\x18+\xec\xd0\x9e\xd1\xd8\xbe.\x85=;\x1f\x13\x97\xee\xed\xdc\xf3\xbb\xb9\x1d\xcel\x1b\xb7\xb7\xdd\xbe~\x98\xbd8>\xfb\xf0\xe1\x92T\xcb\xf4\x89\xae\x8be\x96\xc0\xe4t7l\xd8\xf5U\xb3\xb8\xc1nI\x1e\x86\xb4\x19_@\xf6Big\xc4P\xdb\xc9\xa0\x1d\xbf-}\x05Cp\x17\x00("\xccV \x96\xd1\x94U&k\xfe\x0cy\x81\x81\x8e^\x85')

前一行的输出如下所示

T#                          âXEµP·Í¨6hñpo\S 
Z8LßÈ$5lû¡ùÆ¿sÄ6Dî&Hço«i¦¸½é
           ÍÔ2­ðÒÏ7�)¸¹å-\üm5jõý4üûJÜí+ìÐ
=;îíÜó»¹Îl·Ý¾~TËô   ®eÀät7lØõU³¸ÁnI´_@öBigÄPÛÉ ¿-}Cp("ÌV ÑU&kþ
                                                                  y^

而且输出是加密的乱七八糟。 然后我试着通过复制粘贴机制来完成整个字符串,结果成功了

但是,当我试图通过使用str(<bytes object here>)逐行运行脚本并删除不必要的部分(前导b'和结尾')时,仍然会得到包含所有\x代码的字符串

for i in range(len(data)):
    binary_string = data[i][:-1]
    binary_string = binascii.unhexlify(binary_string)
    binary_string = str(binary_string)[2:-1]
    print(binary_string)

其中数据是file.readlines()的结果

有人能帮我理解发生了什么,为什么一个简单的复制粘贴方法在循环中运行却不起作用


Tags: xdfxfbx03x01xe5xcdxd8xd0
1条回答
网友
1楼 · 发布于 2024-05-13 04:15:46

从表示开始返回的bytes对象

b'\x82\t\x9f\xd4\xe8d13\xb8T\xc8B#\x1e3\xfe\x99`\x1a\xdf\xbb2\xf... etc

实际上是范围为0..255的整数列表。如果你这样做了,你会看到的

>>> x = b'\x82\t\x9f\xd4\xe8d13\xb8T\xc8B#\x1e3\xfe\x99`\x1a\xdf\xbb2\xf... etc
>>> list(x)
[130, 9, 159, 212, 232, 100, 49, 51, 184, 84, 200, 66, 35, 30, ...etc

反斜杠不是数据的一部分:当字节值显示为bytestring时,它们是数据的表示形式。例如,整数列表中显示的第二个值是9。在bytestring显示中,它显示为\t,这是一个ascii水平选项卡,其字节值为9(如果愿意,也可以使用ctrl-i)。类似地,第6到第8个整数值是100, 49, 51,它们是字符“d”、“1”、“3”的ascii值;如果仔细观察,您将在bytestring表示中看到它们在字节\xe8\xb8之间的d13。您会看到d13,因为这些字节可以表示为ascii字符。在这两个字节的任一侧,您可以看到\xe8\xb8,因为这些字节的值为232和184,不能表示为ascii字符,因此显示为十六进制转义

但是,如果您试图将bytestring表示法处理为一个字符序列,这是在调用str()时发生的情况,并扔掉封闭的b'...',那么它不再是一个字节值序列,而是一组曾经表示bytestring的字符。那你就差不多是一个人了

您可能想知道为什么Python的ByTestRing的默认表示形式是混合了十六进制转义(如\xe8)、快捷方式(如\t)和可打印字符。这有几个很好的理由,一个是bytestring通常是文本,而且b'Hello World'b'\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'更友好

要确认这一点,请在Python解释器提示符处粘贴bytestring,如下所示:

>>> b'\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64'
b'Hello World'

相关问题 更多 >