Есть ли способ добавить два байта с переполнением в Python? - PullRequest
3 голосов
/ 11 июня 2009

Я использую pySerial для чтения данных с подключенного устройства. Я хочу рассчитать контрольную сумму каждого полученного пакета. Пакет считывается как массив символов, причем фактическая контрольная сумма является самым последним байтом в конце пакета. Чтобы вычислить контрольную сумму, я обычно суммирую по полезной нагрузке пакета, а затем сравниваю ее с фактической контрольной суммой.

Обычно на языке, подобном C, мы ожидаем переполнения, потому что сама контрольная сумма составляет только один байт. Я не уверен насчет внутренних элементов python, но из моего опыта работы с языком похоже, что по умолчанию будет использоваться переменная большего размера (возможно, какой-то внутренний класс bigInt или что-то в этом роде). Есть ли способ имитировать ожидаемое поведение добавления двух символов без написания собственной реализации? Спасибо.

Ответы [ 3 ]

6 голосов
/ 11 июня 2009

Конечно, просто возьмите модуль вашего результата, чтобы подогнать его к нужному размеру Вы можете сделать модуль в конце или на каждом этапе. Например:

>>> payload = [100, 101, 102, 103, 104] # arbitrary sequence of bytes
>>> sum(payload) % 256 # modulo 256 to make the answer fit in a single byte
254 # this would be your checksum
2 голосов
/ 11 июня 2009

для улучшения более раннего примера, только побитового - и это с 0xFF. не уверен, что Python выполняет оптимизацию по умолчанию или нет.

sum(bytes) & 0xFF
0 голосов
/ 31 августа 2015

Суммирование байтов с последующим получением модуля, как в sum(bytes) % 256 (или sum(bytes) & 0xFF), (во многих языках программирования) уязвимо для целочисленного переполнения, поскольку существует конечное максимальное значение, которое могут представлять целочисленные типы.

Но, поскольку мы говорим о Python, технически это не проблема: целые числа Python имеют произвольную точность, поэтому переполнение целых чисел не может произойти.

Если вы хотите выполнять операцию модуля по элементам, вы можете использовать functools.reduce():

>>> payload = [100, 101, 102, 103, 104] # arbitrary sequence of bytes
# (Python 3 uses functools.reduce() instead of builtin reduce() function)
>>> import functools
>>> functools.reduce(lambda x,y: (x+y)%256, payload)
254
...