我需要验证CRC8-SAE-J1850消息,因此编写了一个脚本,该脚本读取日志并需要从那里计算CRC8(非ZERO)以匹配他们与日志中的CRC8值一起检查,然后检查工具链中的哪一步导致麻烦。了解CRC8 SAE J1850(正常)与“零”的结果
无论如何,我花了一些时间来查看文档,SO帖子和其他人的源代码,但我想坚持使用python更简单的文本处理和接口到我的其他工具。
我发现了在SourceForge上evansneath's Python CRC Implementation一些代码,是很好的直线前进,想搏一搏,但我想如预期它不工作(也许我理解的东西完全错了,但我坚持在这里):
def crc(msg, div, code='11111111'):
"""Cyclic Redundancy Check
Generates an error detecting code based on an inputted message and divisor in the form of a polynomial representation.
Arguments:
msg: The input message of which to generate the output code.
div: The divisor in polynomial form. For example, if the polynomial of x^3 + x + 1 is given, this should be represented as '1011' in the div argument.
code: This is an option argument where a previously generated code may be passed in. This can be used to check validity. If the inputted code produces an outputted code of all zeros, then the message has no errors.
Returns:
An error-detecting code generated by the message and the given divisor.
"""
msg = msg + code
msg = list (msg)
div = list (div)
for i in range (len (msg) - len (code)):
if msg[i] == '1':
for j in range (len (div)):
msg[i+j] = str ((int (msg[i+j])+int (div[j]))%2)
return ''.join (msg[-len (code):])
#Testing:
# Use a divisor that simulates: CRC8 SAE J1850 x^8+x^4+x^3+x^2+x^0
div = '100011101'#0x1D with leading 1 as given by polynomial
msg = '10101001' # 0xA9, just for a Test
print('Input message:', hex(int(msg,2)))
print('Polynomial:', hex(int(div,2)))
o = '11111111'
z = '00000000'
code = crc(msg, div, o)
print('CRC8 code:', hex(int(code,2)))
# Test for output code of '00000000' respectively '11111111' proving that the function worked correctly
print('Success:', crc(msg, div, code) == o)
我检查了结果使用这个发电机: CRC Generator这似乎是唯一一个特色CRC8 SAE J1850零和非零。
现在有趣的部分:为零上述代码工作得很好。
不幸的是,我从我想要检查的软件中得到的CRC代码被初始化,并与两个工具提供完全不同的结果的0xFF('11111111')进行检查。 到目前为止,我甚至无法找到一些脱节的问题(我会评价最有可能的情况),或者通过上述脚本计算出的解决方案和网站上的解决方案之间的数学联系。 该网站符合软件的结果,但上面的python部分没有。
任何人都可以指向我可能错过的文档,或者是另一个问题吗? 在网站上输入消息时,我已经检查了MSB/LSB问题,并尝试使用0xFE进行初始化,如其他代码所示。但没有成功......然而,大多数例子都是基于零的,我没有问题。
编辑:
我检查的计算和通过手的示例去以及打印每一个步骤和所取得的相同。所以在数学上它看起来是正确的,但是SAE除了追加'11111111'这一行然后按位异或,然后移位直到再次出现一个前导符,异或等等,并且将剩余的?这一定是我的理解问题。
Test 1 ---------------------------
Input message: 0xa9
Polynome: 0x11d
['1', '0', '1', '0', '1', '0', '0', '1', '1', '1', '1', '1', '1', '1', '1', 1']
/
['1', '0', '0', '0', '1', '1', '1', '0', '1']
=
current message: ['1', '0', '1', '0', '1', '0', '0', '1', '1', '1', '1', '1', '1 ', '1', '1', '1']
shift 0 Bits
1 XOR 1 = 0
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 0 = 0
1 XOR 1 = 0
0 XOR 1 = 1
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
current message: ['0', '0', '1', '0', '0', '1', '1', '1', '0', '1', '1', '1', '1 ', '1', '1', '1']
shift 2 Bits
1 XOR 1 = 0
0 XOR 0 = 0
0 XOR 0 = 0
1 XOR 0 = 1
1 XOR 1 = 0
1 XOR 1 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
current message: ['0', '0', '0', '0', '0', '1', '0', '0', '1', '1', '0', '1', '1 ', '1', '1', '1']
shift 5 Bits
1 XOR 1 = 0
0 XOR 0 = 0
0 XOR 0 = 0
1 XOR 0 = 1
1 XOR 1 = 0
0 XOR 1 = 1
1 XOR 1 = 0
1 XOR 0 = 1
1 XOR 1 = 0
CRC8 code: 0xab
Reverse Calculation: Check
['1', '0', '1', '0', '1', '0', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1']
/
['1', '0', '0', '0', '1', '1', '1', '0', '1']
=
current message: ['1', '0', '1', '0', '1', '0', '0', '1', '1', '0', '1', '0', '1', '0', '1', '1']
shift 0 Bits
1 XOR 1 = 0
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 0 = 0
1 XOR 1 = 0
0 XOR 1 = 1
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
current message: ['0', '0', '1', '0', '0', '1', '1', '1', '0', '0', '1', '0', '1', '0', '1', '1']
shift 2 Bits
1 XOR 1 = 0
0 XOR 0 = 0
0 XOR 0 = 0
1 XOR 0 = 1
1 XOR 1 = 0
1 XOR 1 = 0
0 XOR 1 = 1
0 XOR 0 = 0
1 XOR 1 = 0
current message: ['0', '0', '0', '0', '0', '1', '0', '0', '1', '0', '0', '0', '1', '0', '1', '1']
shift 5 Bits
1 XOR 1 = 0
0 XOR 0 = 0
0 XOR 0 = 0
1 XOR 0 = 1
0 XOR 1 = 1
0 XOR 1 = 1
0 XOR 1 = 1
1 XOR 0 = 1
0 XOR 1 = 1
CRC correct: True
从你的描述“这是永远不会提到的SAE J1850的输入与0xFF异或“,我认为你还没有完成。只有在链接CRC计算时才有“输入”,即一次计算CRC块,其中输入是前面块的CRC。如果您所做的只是计算消息的CRC,那么除了消息和长度之外,没有其他输入。然后规范提供了什么来初始化寄存器('init')以及什么是异或 - 输出('xorout')。 –
一旦你明白了这一点,那么当链接时为什么需要_initial_ exclusive或带有'xorout'是为了重建上次运行的寄存器内容。 –