#python #string #unicode #encoding #hex
#python #строка #юникод #кодирование #шестнадцатеричный
Вопрос:
У меня есть файл журнала, содержащий шестнадцатеричные строки. Я должен преобразовать его обратно в разборчивое предложение. Однако я замечаю некоторое неустойчивое поведение во время обработки строк.
Например, самая короткая строка в файле журнала
82099fd4e8643133b854c842231e33fe99601adfbb32fe19070dc7b665c27f4510eccdd20c8c68b9ffe6fb941554cb675f92fdfd043a7855f8e5ec1f4b1869595f2ee3e89269d3035c77b3e7d520dc786fecc6074c23565a5de9837627e676676bdbfdeda5d5b52895b2ccdaaa373b5cc8ca7e927d885db6d69fed2175df66b23d21b93b5bdbb619bbde75b39acd42d76778259a4a3653473e74fcd0ec0182401ac5367967c1d8de79cb98fab4bf73b561202042dd94853c0e1375fbd147377de48c7050f660af2f55c572ac53384e3c270c95a20767326f58011139217cef33ae4dd5d94835a1717ad60d478b335d4d78901f51467c0d9e73032f95df834f0105012ae3a9e2b82be5981e340e24b71282b002c512d126c1c6edc868cd13cac190a923cd58e6ec08e48426d1f79969833e4499650e1846c93983efc1364ace994ebf2e12fe41aa0e23214b1f04176ec331967395fd4f3ef374f34dc5ed310748398d87528e3eb0ccde6113151d4cd8634dc755e571a7383a1abdbda4bc9a360c75b444628b5fea075a3ab5ac9d169c565645ed3a14997c3d6e1e62516161986a251ae4c2c3d74c248748d956ffdbaa4dcc6bbd11d2f85f00fdf28cbb0b4bb2143030d0d3b5d0d351756c538785d544c775bbe504089616d32c1903aab5f93e986c2a59dfec2d8e5a380563d3f24be2891835cd5bc6bf73c4803644ee9d5d109c2648e76fab6903a6b8bde98de29c5845b550b7cda83668f1706f5c5388010e200d1954230c4cdf18c824356cfb8c01a1f98493cdd4321195adf0d2cf37951a191429b8b9e5062d5c17fc6d356af5fd34fcfb874a9df39bed83dced182becd09ed1d8be2e853d3b1f1397eeeddcf3bbb91dce6c1bb7b7ddbe7e98bd383efbf0e19254cbf489ae8b6596c0e474376cd8f555b3b8c16e491e86b4195f40f6426967c450dbc9a01dbf2d7d05437017002822cc562096d19455266bfe0c7981818e5e8590555af3ef2e4f39fc70023805095443f5be673be68ed99cd823d82e2b831117377b09ea4375aefb6dac75d2c468264e3d22aa1071aaac220ce1052424e85fc2b52d1b22763b7e5b4a9992f5c67c1d5ead25535cab570ab5c1c9752c39d0a76bd0ffd0bb9bc7e0652edf7014d4da9864619b4d1ed10c2f3c5a3b863e2c8e06a947c831d1f328c8244f1f853c4f2f44ee49eb2ee4251eaebc1a4ef0f0a418fff041f33e9c5d58e904f198bd0e23ab7264a19f3ff1d14b8ee0020f591efb7673bd1ec13d37637c105b442fc2af82b48902b0b22be9086d0cdf3148500c62f72a06994980863f2f0e49c1d6e3a65595c61aa6dbb8d55ce330c617d8a1f3df219347ebec4e2ed4809520208b3af588071e42fdf721c1766bf1461fdad89f00b5dda5d6f538d8e517542bd949b1d6324f625d030b5973f6d0fcfc89242bc1735975c2025e3c40a2102887ad45994734e39b81353e2ea63ae2cae7ecf39a2b6c862762a90dcc8b9bca897874928cb9f7d32cb30c9cd43b2462c636fa26a9e5aa147361584f15f619964b7f8a887c0083e5956dc810d3894c2d228e28d5351210425b2cdbaaf64a702cb6e120130c540e5d29b2cf7fffc0ae7c252d1d09189b52ba82012193527cdf03f8417039dea5028100d5a5ad637ad0e88e91043aa321486e1e7a7a8a78c8ceec015d4c4046f6c75e2d3d53b1b2aec8a4fab6df9654bc93e718d61bdc307a7e7b6feea27b0d03a460f8bf2538d838e48178d649b1e4c76dbbc0c6d63aa35a9827d7fd109a763eadb217a5ec6362e5bfb5a35048b11bed20c3da738bb5385895667014babf04842b983f1272d9d675fa407b2cbb6224f2cad2a3bdfb51c0de8809d69b63e48315c0f31e51cd2a555ac9781b5e40d787a1ea297a78b3d7cc0ad0d907b28940c3c9819d156b869507c1cf3c982e17
Я использую следующий фрагмент, чтобы преобразовать его в объект bytes
binascii.unhexlify(line[:-1])
[:-1] для удаления символа конечной строки в конце.
Я возвращаю объект bytes следующим образом
b'x82tx9fxd4xe8d13xb8Txc8B#x1e3xfex99`x1axdfxbb2xfex19x07rxc7xb6exc2x7fEx10xecxcdxd2x0cx8chxb9xffxe6xfbx94x15Txcbg_x92xfdxfdx04:xUxf8xe5xecx1fKx18iY_.xe3xe8x92ixd3x03\wxb3xe7xd5 xdcxoxecxc6x07L#VZ]xe9x83v'xe6vgkxdbxfdxedxa5xd5xb5(x95xb2xccxdaxaa7;\xc8xca~x92}x88]xb6xd6x9fxed!uxdffxb2=!xb9;[xdbxb6x19xbbxdeuxb3x9axcdBxd7gx%x9aJ6SG>txfcxd0xecx01x82@x1axc56ygxc1xd8xdeyxcbx98xfaxb4xbfsxb5a Bxddx94x85<x0ex13uxfbxd1G7}xe4x8cpPxf6`xaf/Uxc5rxacS8N<'x0cx95xa2x07g2oXx01x119!|xef3xaeMxd5xd9H5xa1qzxd6rGx8b3]Mxx90x1fQF|rx9esx03/x95xdfx83Ox01x05x01*xe3xa9xe2xb8 xe5x98x1e4x0e$xb7x12x82xb0x02xc5x12xd1amp;xc1xc6xedxc8hxcdx13xcaxc1x90xa9#xcdXxe6xecx08xe4x84amp;xd1xf7x99ix83>Dx99ex0ex18Fxc99x83xefxc16Jxcex99Nxbf.x12xfeAxaax0e#!Kx1fx04x17nxc31x96sx95xfdO>xf3txf3Mxc5xed1x07H9x8dx87Rx8e>xb0xccxdeax13x15x1dLxd8cMxc7Uxe5qxa78:x1axbdxbdxa4xbcx9a6x0cuxb4Dbx8b_xeax07Z:xb5xacx9dx16x9cVVExed:x14x99|=nx1ebQaax98j%x1axe4xc2xc3xd7L$x87Hxd9VxffxdbxaaMxcckxbdx11xd2xf8_x00xfdxf2x8cxbbx0bKxb2x1400xd0xd3xb5xd0xd3QulSx87x85xd5Dxc7uxbbxe5x04x08x96x16xd3,x19x03xaaxb5xf9>x98l*Yxdfxec-x8eZ8x05cxd3xf2Kxe2x89x185xcd[xc6xbfsxc4x806Dxeex9d]x10x9camp;Hxe7oxabix03xa6xb8xbdxe9x8dxe2x9cXExb5Pxb7xcdxa86hxf1po\Sx88x01x0e rx19T#x0cLxdfx18xc8$5lxfbx8cx01xa1xf9x84x93xcdxd42x11x95xadxf0xd2xcf7x95x1ax19x14)xb8xb9xe5x06-\x17xfcm5jxf5xfd4xfcxfbx87Jx9dxf3x9bxedx83xdcxedx18 xecxd0x9exd1xd8xbe.x85=;x1fx13x97xeexedxdcxf3xbbxb9x1dxcelx1bxb7xb7xddxbe~x98xbd8>xfbxf0xe1x92Txcbxf4x89xaex8bex96xc0xe4t7lxd8xf5Uxb3xb8xc1nIx1ex86xb4x19_@xf6Bigxc4Pxdbxc9xa0x1dxbf-}x05Cpx17x00("xccV x96xd1x94Uamp;kxfex0cyx81x81x8e^x85x90UZxf3xef.O9xfcpx028x05tTCxf5xbeg;xe6x8exd9x9cxd8#xd8. x83x11x177{txeaCuxaexfbmxacuxd2xc4hamp;N="xaax10qxaaxac"x0cxe1x05$xe8_xc2xb5-x1b"v;~[Jx99x92xf5xc6|x1d^xad%S\xabWnxb5xc1xc9u,9xd0xa7kxd0xffxd0xbbx9bxc7xe0e.xdfpx14xd4xdax98dax9bMx1exd1x0c/<Z;x86>,x8ex06xa9Gxc81xd1xf3(xc8$Ox1fx85<O/DxeeIxeb.xe4%x1exaexbcx1aNxf0xf0xa4x18xffxf0Axf3>x9c]Xxe9x04xf1x98xbdx0e#xabrdxa1x9f?xf1xd1Kx8exe0x02x0fYx1exfbvsxbdx1exc1=7c|x10[D/xc2xafx82xb4x89x02xb0xb2 xe9x08mx0cxdf1HPx0cbxf7*x06x99Ix80x86?/x0eIxc1xd6xe3xa6Ux95xc6x1axa6xdbxb8xd5\xe30xc6x17xd8xa1xf3xdf!x93GxebxecN.xd4x80x95 x8b:xf5x88x07x1eBxfdxf7!xc1vkxf1Fx1fxdaxd8x9fx00xb5xddxa5xd6xf58xd8xe5x17T xd9Ixb1xd62Ob]x03x0bYsxf6xd0xfcxfcx89$ xc1sYuxc2x02^<@xa2x10(x87xadEx99G4xe3x9bx815>.xa6:xe2xcaxe7xecxf3x9a lx86'bxa9rxccx8bx9bxcax89xtx92x8cxb9xf7xd3,xb3x0cx9cxd4;$bxc66xfaamp;xa9xe5xaax14saXOx15xf6x19x96Kx7fx8ax88|x00x83xe5x95mxc8x10xd3x89L-"x8e(xd55x12x10B[,xdbxaaxf6Jp,xb6xe1 x13x0cTx0e])xb2xcfx7fxffxc0xae|%-x1dtx18x9bRxbax82x01!x93R|xdfx03xf8Ap9xdexa5x02x81x00xd5xa5xadczxd0xe8x8ex91x04:xa3!Hnx1ezzx8axxc8xcexecx01]L@Fxf6xc7^-=Sxb1xb2xaexc8xa4xfaxb6xdfx96Txbcx93xe7x18xd6x1bxdc0z~{oxeexa2{rx03xa4`xf8xbf%8xd88xe4x81xxd6Ixb1xe4xc7mxbbxc0xc6xd6:xa3Zx98'xd7xfdx10x9av>xadxb2x17xa5xeccbxe5xbfxb5xa3PHxb1x1bxed xc3xdasx8bxb58Xx95fpx14xbaxbfx04x84 x98?x12rxd9xd6uxfa@{,xbbb$xf2xcaxd2xa3xbdxfbQxc0xdex88txd6x9bcxe4x83x15xc0xf3x1eQxcd*UZxc9xx1b^@xd7x87xa1xea)zxxb3xd7xccnxd0xd9x07xb2x89@xc3xc9x81x9dx15kx86x95x07xc1xcf<x98.x17'
Теперь я понимаю, что это шестнадцатеричные коды, и будет «декодированная» версия этого.
Теперь, по какой-то причине, я скопировал часть строки, присвоил ее переменной и напечатал ее нормально, она выдала «декодированную» версию (хотя это была случайная тарабарщина, но она работает)
print('x98l*Yxdfxec-x8eZ8x05cxd3xf2Kxe2x89x185xcd[xc6xbfsxc4x806Dxeex9d]x10x9camp;Hxe7oxabix03xa6xb8xbdxe9x8dxe2x9cXExb5Pxb7xcdxa86hxf1po\Sx88x01x0e rx19T#x0cLxdfx18xc8$5lxfbx8cx01xa1xf9x84x93xcdxd42x11x95xadxf0xd2xcf7x95x1ax19x14)xb8xb9xe5x06-\x17xfcm5jxf5xfd4xfcxfbx87Jx9dxf3x9bxedx83xdcxedx18 xecxd0x9exd1xd8xbe.x85=;x1fx13x97xeexedxdcxf3xbbxb9x1dxcelx1bxb7xb7xddxbe~x98xbd8>xfbxf0xe1x92Txcbxf4x89xaex8bex96xc0xe4t7lxd8xf5Uxb3xb8xc1nIx1ex86xb4x19_@xf6Bigxc4Pxdbxc9xa0x1dxbf-}x05Cpx17x00("xccV x96xd1x94Uamp;kxfex0cyx81x81x8e^x85')
Вывод предыдущей строки выглядит следующим образом
T# âXEµP·Í¨6hñpoS
Z8LßÈ$5lû¡ùÆ¿sÄ6Dîamp;Hço«i¦¸½é
ÍÔ2ðÒÏ7�)¸¹å-üm5jõý4üûJÜí ìÐ
=;îíÜó»¹Îl·Ý¾~TËô ®eÀät7lØõU³¸ÁnI´_@öBigÄPÛÉ ¿-}Cp("ÌV ÑUamp;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() .
Может кто-нибудь помочь мне понять, что происходит и почему простой метод копирования-вставки работает, а запуск его через цикл не работает?
Ответ №1:
bytes
Объект, который вы получаете обратно с началом представления
b'x82tx9fxd4xe8d13xb8Txc8B#x1e3xfex99`x1axdfxbb2xf... etc
на самом деле это список целых чисел в диапазоне 0..255. Вы увидите это, если сделаете
>>> x = b'x82tx9fxd4xe8d13xb8Txc8B#x1e3xfex99`x1axdfxbb2xf... etc
>>> list(x)
[130, 9, 159, 212, 232, 100, 49, 51, 184, 84, 200, 66, 35, 30, ...etc
Обратная косая черта не является частью данных: они представляют собой представление данных, когда байтовые значения отображаются в виде байтовой строки. Например, 2-е значение, показанное в списке целых чисел, равно 9. На дисплее bytestring он отображается как t
горизонтальная вкладка ascii, для которой значение байта равно 9 (или ctrl-i, если вы предпочитаете). Аналогично, с 6-го по 8-е целочисленные значения — 100, 49, 51
это значения ascii для d символов’, ‘1’, ‘3’; и если вы присмотритесь повнимательнее , то увидите их в представлении bytestring как d13
между байтами xe8
и xb8
. Вы видите d13
, потому что эти байты могут быть представлены в виде символов ascii. По обе стороны от того, что вы видите xe8
, и xb8
потому, что эти байты имеют значения 232 и 184, которые не могут быть представлены в виде символов ascii, и поэтому отображаются в виде шестнадцатеричных экранирований.
Но если вы попытаетесь обработать представление bytestring как последовательность символов, что и происходит, когда вы вызываете str()
его, и отбрасываете заключающее b'...'
, то это уже не последовательность байтовых значений, а скорее набор символов, которые когда-то представляли собой байтовую строку. Тогда вы более или менее предоставлены сами себе.
Вы, вероятно, задаетесь вопросом, почему представление байтовых строк в Python по умолчанию представляет собой смесь шестнадцатеричных экранирований xe8
, подобных ярлыкам t
, и печатаемых символов. Для этого есть несколько веских причин, одна из которых заключается в том, что байтовые строки часто являются текстовыми и b'Hello World'
более удобными, чем b'x48x65x6cx6cx6fx20x57x6fx72x6cx64'
.
Чтобы подтвердить это, вставьте эту байтовую строку в приглашение интерпретатора Python, например:
>>> b'x48x65x6cx6cx6fx20x57x6fx72x6cx64'
b'Hello World'