在 python 中计算 crc8 dvb s2
Calculate crc8 dvb s2 in python
我需要在 python 中计算 crc8 dvb s2 校验和,但是我找不到任何关于这个校验和真正工作原理的有用信息,所以我尝试转换这个工作的 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 too big to convert。
我的代码显然有问题,导致数字越来越大,但我无法弄清楚到底是什么。
完整回溯:
---------------------------------------------------------------------------
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
int.to_bytes
的文档说:
An OverflowError
is raised if the integer is not representable with
the given number of bytes.
您使用.to_bytes(1, byteorder='little')
的数字似乎大于255(一个字节可表示的最大数字)。
这个:
int.from_bytes( b2, byteorder='little')).to_bytes(1, byteorder='little')
只有在 b2
介于 0 和 255 之间时才有效,我不明白将相同的值从整数转换为字节再返回的意义何在。
你打算计算b2
二进制表示的最低8位吗?那么你应该使用 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
我需要在 python 中计算 crc8 dvb s2 校验和,但是我找不到任何关于这个校验和真正工作原理的有用信息,所以我尝试转换这个工作的 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 too big to convert。
我的代码显然有问题,导致数字越来越大,但我无法弄清楚到底是什么。
完整回溯:
---------------------------------------------------------------------------
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
int.to_bytes
的文档说:
An
OverflowError
is raised if the integer is not representable with the given number of bytes.
您使用.to_bytes(1, byteorder='little')
的数字似乎大于255(一个字节可表示的最大数字)。
这个:
int.from_bytes( b2, byteorder='little')).to_bytes(1, byteorder='little')
只有在 b2
介于 0 和 255 之间时才有效,我不明白将相同的值从整数转换为字节再返回的意义何在。
你打算计算b2
二进制表示的最低8位吗?那么你应该使用 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