2017-02-20 32 views
0

Я пытаюсь перевести этот Python 2 код Python 3.Транслейтинг Python 2 байта контрольной суммы калькулятор на Python 3

def calculate_checksum(packet): 
    total = 0 
    for char in packet: 
    total += struct.unpack('B', char)[0] 
    return (256 - (total % 256)) & 0xff 

В Python 3 он вызывает TypeError:

total += struct.unpack('B', char)[0] 
TypeError: a bytes-like object is required, not 'int' 

У меня есть пытался исследовать изменения в строках и байтах, но это немного подавляющее.

+0

Вместо этого я попробую 'bytes (char)'. но [mcve] был бы лучшим способом убедиться. –

+1

@ Jean-FrançoisFabre: весь вызов 'struct' * избыточен *. Все, что он делает, это превратить один символ (unsigned char) в их целочисленный эквивалент для этого байта. Это функция 'ord()', в основном. За исключением Python 3, итерация по байтам уже дает вам целые числа. –

+0

@MartijnPieters конечно! иногда я забываю посмотреть на большую картинку –

ответ

2

Код в основном преобразует отдельные символы в байтах в их целочисленный эквивалент; характер \x42 становится 0x42 (или десятичное 66), например:

>>> # Python 2 
... 
>>> struct.unpack('B', '\x42')[0] 
66 

Как и в сторону, вы могли бы сделать то же самое более просто с ord() function:

>>> ord('\x42') 
66 

В Python 3, вы уже получить целые числа, когда вы итерацию над bytes объекта, поэтому вы получаете свою ошибку:

>>> # Python 3 
... 
>>> b'\x42'[0] 
66 

Весь struct.unpack() вызов может быть просто отбрасывается:

for char in packet: 
    total += char 

или просто использовать sum() для расчета общей в одном шаге:

total = sum(packet) 

делает полную версию:

def calculate_checksum_ord(packet): 
    total = sum(ord(c) for c in packet) 
    return (256 - (total % 256)) & 0xff 

Обратите внимание, что код Python 2 также может использовать sum() с функцией ord(), а не использовать struct: total = sum(ord(c) for c in packed).