Рассчитать crc8 DVB S2 в Python - PullRequest
0 голосов
/ 25 октября 2018

Мне нужно вычислить контрольную сумму crc8 dvb s2 в python, но я не могу найти никакой полезной информации о том, как эта контрольная сумма действительно работает, поэтому я попытался преобразовать этот рабочий код C:

uint8_t crc8_dvb_s2(uint8_t crc, unsigned char a)

    {
        crc ^= a;
        for (int ii = 0; ii < 8; ++ii) {
            if (crc & 0x80) {
                crc = (crc << 1) ^ 0xD5;
            } else {
                crc = crc << 1;
            }
        }
        return crc;
    }

вкод Python:

import crc8
import operator 
def bxor(b1, b2): # use xor for bytes
    return bytes(map(operator.xor, b1, b2))
def blshift(b1, b2): # use shift left for bytes
    return (int.from_bytes( b1, byteorder='little') << int.from_bytes( b2, byteorder='little')).to_bytes(1, byteorder='little')
def _checksum(message): 
    #calculate crc
    crc = crc8.crc8()
    crc.update(message)
    crc_result = crc.digest()
    #calculate dvb
    crc_result = bxor(crc_result , message)
    for i in range(0, 7):
        if (crc_result == b'\x80') :
            crc_result = bxor((blshift(crc_result, b'\x01')) , b'\xD5')
        else:
            crc_result = blshift(crc_result, b'\x01')
    #-------------
    return crc_result;

Но с этим что-то не так, что я не могу понять.Если я даю функции C байты '\ x00d \ x00 \ x00 \ x00', то в результате я получаю в результате '\ x8f' (что правильно), а функция Python дает мне OverflowError: int, слишком большой для преобразования.

В моем коде явно что-то не так, что цифры увеличиваются и увеличиваются, но я не смог понять, что именно.

Полная обратная трассировка:

---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
<ipython-input-226-8288eada1ce9> in <module>
----> 1 _checksum(b'\x00d\x00\x00\x00')

<ipython-input-225-2e5beaea293f> in _checksum(message)
     18             crc_result = bxor((blshift(crc_result, b'\x01')) , b'\xD5')
     19         else:
---> 20             crc_result = blshift(crc_result, b'\x01')
     21     #-------------
     22     return crc_result;

<ipython-input-225-2e5beaea293f> in blshift(b1, b2)
      6     return bytes(map(operator.and_, b1, b2))
      7 def blshift(b1, b2): # use shift left for bytes
----> 8     return (int.from_bytes( b1, byteorder='little') << int.from_bytes( b2, byteorder='little')).to_bytes(1, byteorder='little')
      9 def _checksum(message):
     10     #calculate crc

OverflowError: int too big to convert

1 Ответ

0 голосов
/ 25 октября 2018

Документация int.to_bytes гласит:

Значение OverflowError повышается, если целое число не представимо с данным числом байтов.

Кажется, что число, на котором вы используете .to_bytes(1, byteorder='little'), больше 255 (наибольшее число, представляемое одним байтом).

Это:

int.from_bytes( b2, byteorder='little')).to_bytes(1, byteorder='little')

может работать, только если b2 находится в диапазоне от 0 до 255, и я не понимаю, в чем смысл преобразования того же значения из целого числа в байты и обратно.

Вы намереваетесьвычислить младшие 8 бит двоичного представления b2?Затем вы должны использовать b2 % 256.


Вы должны иметь возможность переводить эту функцию C почти буквально в Python, без необходимости использования вспомогательных функций, таких как bxor или blshift:

def crc8_dvb_s2(crc, a):
    crc ^= a
    for _ in range(8):
        if crc & 0x80:
            crc = ((crc << 1) ^ 0xD5) % 256
        else:
            crc = (crc << 1) % 256
    return crc
...