Метод декодирования выдает ошибку в Python 3 - PullRequest
0 голосов
/ 11 января 2020

Аналогично этот другой вопрос по декодированию шестнадцатеричной строки , у меня есть код в скрипте Python 2.7, который работал годами. Сейчас я пытаюсь преобразовать этот скрипт в Python 3.

ОК, я прошу прощения за то, что не опубликовал полный вопрос изначально. Я надеюсь, что это проясняет ситуацию.

Проблема в том, что я пытаюсь преобразовать старый Python 2.7 скрипт в Python 3.8. По большей части преобразование прошло нормально, но у меня возникли проблемы с преобразованием следующего кода:

# get Register Stings
RegString = ""
for i in range(length):
    if regs[start+i]!=0:
        RegString = RegString + str(format(regs[start+i],'x').decode('hex'))

Вот некоторые вспомогательные данные:

regs[start+0] = 20341
regs[start+1] = 29762

Я думаю, что мой Python 2.7 код преобразует их в HEX как «4f75» и «7442», соответственно. И затем к символам "Ou" и "tB" соответственно.

В Python 3 я получаю эту ошибку:

'str' объект не имеет атрибута 'decode'

Моя цель состоит в том, чтобы изменить мой код Python 3, чтобы скрипт генерировал те же результаты.

1 Ответ

0 голосов
/ 11 января 2020

str(format(regs[start+i],'x').decode('hex')) - очень многословный и округлый способ преобразования ненулевых целочисленных значений в regs[start:start + length] в отдельные символы строки байтов (str в Python 2 действительно следует рассматривать как последовательность байт). Сначала он преобразует целочисленное значение в шестнадцатеричное представление (строку), декодирует эту шестнадцатеричную строку в (серию) строковых символов, затем вызывает str() результата (избыточно, значение уже является строкой). Предполагая, что значения в regs являются целыми числами в диапазоне 0-255 (или даже 0-127), в Python 2 это действительно должно было бы использовать функцию chr() .

Если вы хотите сохранить l oop, используйте chr() (чтобы получить строковое значение str) или, если вам нужно двоичное значение, используйте bytes([...]). Итак:

RegString = ""
for codepoint in regs[start:start + length]:
    RegString += chr(codepoint)

или

RegString = b""
for codepoint in regs[start:start + length]:
    RegString += bytes([codepoint])

Поскольку это фактически преобразование последовательности целых чисел, вы можете просто передать весь лот в bytes() и отфильтровать обнулять нули, как вы go:

# only take non-zero values
RegString = bytes(b for b in regs[start:start + length] if b)

или впоследствии удалить нулевые значения:

RegString = bytes(regs[start:start + length]).replace(b"\x00", b"")

Если это все еще должна быть строка, а не байтовое значение, вы можете затем декодировать его с любой подходящей кодировкой (ASCII, если целые числа находятся в диапазоне 0-127, или более конкретный c код c в противном случае, в Python 2 этот код выдает строку байта поэтому поищите другие подсказки в коде относительно того, какую кодировку они могли использовать).

...