Байт Python представление шестнадцатеричной строки, которая является EBCDIC

У меня есть строка в шестнадцатеричном виде:

Hex = 'E388854083969497A4A38599408881A2409985829696A38584408699969440814082A48783888583924B'

Как объект байта это выглядит так:

b'\xe3\x88\x85@'b'\xe3\x88\x85@\x83\x96\x94\x97\xa4'b'\xe3\x88\x85@'b'\xe3\x88\x85@\x83\x96\x94\x97\xa4'b'\xe3\x88\x85@\x83'b'\xe3\x88'b'\xe3\x88\x85@\x83\x96\x94\x97\xa4'

В EBCDIC это так:

The computer has rebooted from a bugcheck.

Итак, я знаю, что hex 40 (x40) - это "пробел" в EBCDIC и "@" в ASCII

Я не могу понять, почему python при печати байтовых объектов печатает "@" вместо "\x40"

мой пример тестового кода:

import codecs
Hex = 'E388854083969497A4A38599408881A2409985829696A38584408699969440814082A48783888583924B'

output = []
DDF = [4,9,4,9,5,2,9]
distance = 0

# This breaks my hex string into chunks based off the list 'DDF'
for x in DDF:
    output.append(Hex[distance:x*2+distance])
    distance += x*2

#This prints out the list of hex strings
for x in output:
    print(x)

#This prints out they byte objects in the list
for x in output:
    x = codecs.decode(x, "hex")
    print(x)

#The next line print the correct text
Hex = codecs.decode(Hex, "hex")
print(codecs.decode(Hex, 'cp1140'))

Результатом вышесказанного является:

E3888540
83969497A4A3859940
8881A240
9985829696A3858440
8699969440
8140
82A48783888583924B
b'\xe3\x88\x85@'
b'\x83\x96\x94\x97\xa4\xa3\x85\x99@'
b'\x88\x81\xa2@'
b'\x99\x85\x82\x96\x96\xa3\x85\x84@'
b'\x86\x99\x96\x94@'
b'\x81@'
b'\x82\xa4\x87\x83\x88\x85\x83\x92K'
The computer has rebooted from a bugcheck.

Поэтому я предполагаю, что мой вопрос заключается в том, как заставить Python печатать байтовый объект как "x40" вместо "@"

Спасибо большое за вашу помощь:)

2 ответа

Решение

Я думаю, что ваш байтовый массив немного отключен.

В соответствии с этим вам необходимо использовать "cp500" для декодирования, например:

my_string_in_hex = 'E388854083969497A4A38599408881A2409985829696A38584408699969440814082A48783888583924B'
my_bytes = bytearray.fromhex(my_string_in_hex)
print(my_bytes)

my_string = my_bytes.decode('cp500')
print(my_string)

выход:

bytearray(b'\xe3\x88\x85@\x83\x96\x94\x97\xa4\xa3\x85\x99@\x88\x81\xa2@\x99\x85\x82\x96\x96\xa3\x85\x84@\x86\x99\x96\x94@\x81@\x82\xa4\x87\x83\x88\x85\x83\x92K')
The computer has rebooted from a bugcheck.

Когда вы печатаете bytearray, он все равно будет печатать '@', однако он будет действительным \x40 "под крышками". Это просто __repr__() объекта. Так как этот метод не использует какой-либо параметр decode для его правильного декодирования, он просто создает "читаемую" строку для печати.

__repr__() или же repr() " просто так "; это только " представление объекта ", а не фактический объект. Это не значит, что на самом деле это "@". Я просто использую этот символ при печати. Это все еще байтовый массив, а не строка.

При декодировании он будет правильно декодироваться, используя выбранную кодовую страницу.

Python всегда пытается сначала декодировать hex как печатный символ (читай: ASCII) при печати через print(), Если вам нужна полная шестнадцатеричная строка, используйте binascii.hexlify():

Hex = 'E388854083969497A4A38599408881A2409985829696A38584408699969440814082A48783888583924B'

binascii.hexlify(codecs.decode(Hex,'hex'))

>>>> b'e388854083969497a4a38599408881a2409985829696a38584408699969440814082a48783888583924b'
Другие вопросы по тегам