首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >了解CRC8 SAE J1850 (正常)的结果。“零”

了解CRC8 SAE J1850 (正常)的结果。“零”
EN

Stack Overflow用户
提问于 2016-07-28 14:33:50
回答 2查看 15.4K关注 0票数 2

我需要对CRC8-SAE-J1850消息进行验证,并因此编写了一个脚本,从那里读取日志并计算CRC8 (非零),以便将它们与日志中的CRC8值匹配,然后检查工具链中的哪个步骤引起了麻烦。

无论如何,我花了一些时间研究文档,所以文章和其他人的源代码,但我想继续使用python,以便更容易的文本处理和接口到我的其他工具。

我在sourceforge evansneath的Python实现上找到了一些代码,这些代码非常直接,我想让它试一试,但我认为它不像预期的那样工作(也许我理解了一些完全错误的东西,但我被困在这里了):

代码语言:javascript
复制
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发生器,它似乎是唯一一个具有CRC8、SAE、J1850、0和非零的特性。

有趣的部分是:对于零,上面的代码工作得非常好。

不幸的是,我从我要检查的软件中获得的CRC代码被初始化,并根据0xFF ('11111111')进行检查,这两个工具提供的结果完全不同。到目前为止,我甚至还没能找到一些零散的问题(我认为这是最有可能的情况),或者上面的脚本计算的解决方案和网站计算的解决方案之间的数学联系。该网站符合软件的结果,但上面的python部分没有。

有人能告诉我一个我可能错过的文档,或者是另一个问题吗?当我在网站上输入消息时,我已经检查了MSB/LSB问题,并尝试过像其他代码建议的那样使用0xFE初始化。但没有成功..。然而,大多数例子都是以零为基础的,因此我没有问题。

编辑

我检查了计算,并通过一个例子,以及打印的每一步,并实现了同样的。因此,从数学上看,这似乎是正确的,但SAE除了在“11111111”和“异或”的位上加上一行,然后移动到再次出现领先的行,异或-ing等之外,还在做什么?把剩下的吐出来?这一定是我这边的理解问题。

代码语言:javascript
复制
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
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-08-11 07:22:09

我解决了。

从来没有提到对于SAE J1850,输入是带有0xFF的XORed。尽管C代码Mark提供了精确的声明,但是它并没有帮助我理解我的问题所在。

这不是一个bug,我的代码工作正常,但这是我假设的前提。

这就是为什么C代码没有帮助我解决这个问题,因为我从来没有理解这是问题的第一。

SAE J1850计算的修正代码(使用XORin 0xFF、XORout 0xFF、无反射、非反向、多项式0x1D)逐位计算如下。

代码的学分仍然保留在关于github的事件中,我只是更改了输入。

代码语言:javascript
复制
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.
"""
# Append the code to the message. If no code is given, default to '1111111'
# Uncomment every occurence of msg_XORIN if not CRC-8 SAE J1850 
msg_XORIN = [] # XOR the input before appending the code
msg_XORIN = [str((int(msg[i])+1) %2) for i in range(len(list(msg)))]
msg = msg_XORIN

div = list(div)
msg = list(msg) + list(code) # Convert msg and div into list form for easier handling

# Loop over every message bit (minus the appended code)
for i in range(len(msg)-len(code)):
    # If that messsage bit is not one, shift until it is.
    if msg[i] == '1':
        for j in range(len(div)):
            # Perform modulo 2 ( == XOR) on each index of the divisor
            msg[i+j] = str((int(msg[i+j])+int(div[j]))%2)

# Output the last error-checking code portion of the message generated

return ''.join(msg[-len(code):])

试题中的试题可以继续进行。调用一次生成CRC,用msg +生成crc再次调用验证。

好消息来源:http://reveng.sourceforge.net/crc-catalogue/1-15.htm#crc.cat-bits.8

票数 0
EN

Stack Overflow用户

发布于 2016-07-29 01:53:50

通常使用以下参数来定义CRC:

代码语言:javascript
复制
width=8 poly=0x1d init=0xff refin=false refout=false xorout=0xff check=0x4b name="CRC-8/SAE-J1850"

crcgen将使用它并生成C代码来计算CRC。如果您愿意,可以轻松地将其转换为Python。以下是crcgen中C中的逐位例程:

代码语言:javascript
复制
#include <stdint.h>

unsigned crc8sae_j1850_bit(unsigned crc, unsigned char const *data, size_t len) {
    if (data == NULL)
        return 0;
    crc ^= 0xff;
    while (len--) {
        crc ^= *data++;
        for (unsigned k = 0; k < 8; k++)
            crc = crc & 0x80 ? (crc << 1) ^ 0x1d : crc << 1;
    }
    crc &= 0xff;
    crc ^= 0xff;
    return crc;
}

链接CRC计算器页面中列出的“零”版本具有以下参数,只需将初始值和xorout值更改为零:

代码语言:javascript
复制
width=8 poly=0x1d init=0x00 refin=false refout=false xorout=0x00 check=0x37 name="CRC-8/SAE-J1850-ZERO"

下面是crcgen中的C中的逐位例程:

代码语言:javascript
复制
#include <stdint.h>

unsigned crc8sae_j1850_zero_bit(unsigned crc, unsigned char const *data, size_t len) {
    if (data == NULL)
        return 0;
    while (len--) {
        crc ^= *data++;
        for (unsigned k = 0; k < 8; k++)
            crc = crc & 0x80 ? (crc << 1) ^ 0x1d : crc << 1;
    }
    crc &= 0xff;
    return crc;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38639423

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档