差异升压CRC和linux / lib目录/ CRC-ccitt.c [英] Difference in Boost CRC and linux/lib/crc-ccitt.c

查看:816
本文介绍了差异升压CRC和linux / lib目录/ CRC-ccitt.c的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个来源,计算看似相同的CRC值。
我想不通,为什么'升压/ crc.hpp'实现从Linux的/ lib目录/ CRC-ccitt.c'实现不同。

I have two sources to calculate the seemingly same crc value. I can not figure out why the 'boost/crc.hpp' implementation differs from the 'linux/lib/crc-ccitt.c' implementation.

CRC-ccitt.c
提振

下面是说明该问题的例子。
这是sligthly较长时间,因为我没有我的电脑上的Linux内核源代码。
它编译,如果你链接的推动它。

Here is an example that illustrates the Problem. It is sligthly longer since i do not have the Linux kernel source on my Computer. It compiles if you link boost to it.

问题是,Linux和升压不要在CRC值一致。
Linux源指出:

The Problem is that Linux and boost do not agree on the crc value. The Linux source states that:


  • 多项式... 0x8408。

  • 添加隐式X ^ 16,你有标准的CRC-CCITT。

我不知道如何应用X ^ 16,但我死了编辑这个问题反映偏离多项式。

I do not know how to apply x^16 but i die edit this question to reflect the deviating polynomial.

#include <stdio.h>
#include <boost\crc.hpp>

typedef unsigned short u16;
typedef unsigned char u8;

/*
*   linux/lib/crc-ccitt.c
*
*   This source code is licensed under the GNU General Public License,
*   Version 2. See the file COPYING for more details.
*/

/*modified for minimal example on stackoverflow*/
/*original source from http://mirrors.neusoft.edu.cn/rpi-kernel/lib/crc-ccitt.c */

u16 const crc_ccitt_table[256] = {
    0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
    0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
    0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
    0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
    0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
    0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
    0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
    0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
    0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
    0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
    0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
    0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
    0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
    0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
    0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
    0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
    0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
    0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
    0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
    0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
    0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
    0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
    0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
    0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
    0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
    0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
    0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
    0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
    0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
    0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
    0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
    0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
};

//from crc-ccitt.h
static inline u16 crc_ccitt_byte(u16 crc, const u8 c)
{
    return (crc >> 8) ^ crc_ccitt_table[(crc ^ c) & 0xff];
}

u16 crc_ccitt(u16 crc, u8 const *buffer, size_t len)
{
    while (len--)
        crc = crc_ccitt_byte(crc, *buffer++);
    return crc;
}

#define check(X, Y) \
if (X != Y) { \
    printf("%s !=  %s\n", #X, #Y); \
} else { \
    printf("%s ==  %s   !!! celebrate\n", #X, #Y); \
} 

void runTestSet(unsigned char * data, unsigned size)
{
    u16 linux = crc_ccitt(0xFFFF, data, size);

    boost::crc_ccitt_type boost_crc_ccitt_type;
    boost::crc_16_type boost_crc_16_type;
    boost::crc_32_type boost_crc_32_type;
    boost::crc_xmodem_type boost_crc_xmodem_type;
    boost::crc_optimal<16, 0x8408, 0xFFFF, 0, false, false> boost_crc_optimal_16_8408_FFFF_0_0_0;
    boost::crc_optimal<16, 0x8408, 0xFFFF, 0, true, true> boost_crc_optimal_16_8408_FFFF_0_1_1;
    boost::crc_optimal<16, 0xA001, 0xFFFF, 0, true, true> boost_crc_optimal_16_A001_FFFF_0_1_1;
    boost::crc_optimal<16, 0x8408, 0xFFFF, 0, true, false> boost_crc_optimal_16_8408_FFFF_0_1_0;
    boost::crc_optimal<16, 0x856F, 0xFFFF, 0, true, true> boost_crc_optimal_16_856F_FFFF_0_1_1;
    boost::crc_optimal<16, 0x856F, 0xFFFF, 0, true, false> boost_crc_optimal_16_856F_FFFF_0_1_0;

    boost_crc_ccitt_type.process_bytes(data, size);
    boost_crc_16_type.process_bytes(data, size);
    boost_crc_32_type.process_bytes(data, size);
    boost_crc_xmodem_type.process_bytes(data, size);
    boost_crc_optimal_16_8408_FFFF_0_0_0.process_bytes(data, size);
    boost_crc_optimal_16_8408_FFFF_0_1_1.process_bytes(data, size);
    boost_crc_optimal_16_A001_FFFF_0_1_1.process_bytes(data, size);
    boost_crc_optimal_16_8408_FFFF_0_1_0.process_bytes(data, size);
    boost_crc_optimal_16_856F_FFFF_0_1_1.process_bytes(data, size);
    boost_crc_optimal_16_856F_FFFF_0_1_0.process_bytes(data, size);

    printf("Testing with sequence: '");
    for (unsigned n = 0; n < size; ++n)
    {
        if (n > 0) printf(" ");
        printf("0x%02X", data[n]);
    }
    printf("'\n");
    check(boost_crc_ccitt_type.checksum(), linux);
    check(boost_crc_16_type.checksum(), linux);
    check(boost_crc_32_type.checksum(), linux);
    check(boost_crc_xmodem_type.checksum(), linux);
    check(boost_crc_optimal_16_8408_FFFF_0_0_0.checksum(), linux);
    check(boost_crc_optimal_16_8408_FFFF_0_1_1.checksum(), linux);
    check(boost_crc_optimal_16_A001_FFFF_0_1_1.checksum(), linux);
    check(boost_crc_optimal_16_8408_FFFF_0_1_0.checksum(), linux);
    check(boost_crc_optimal_16_856F_FFFF_0_1_1.checksum(), linux);
    check(boost_crc_optimal_16_856F_FFFF_0_1_0.checksum(), linux);
    printf("End Of Testrun\n\n");
}


int main()
{
    unsigned char simple[] = {0x80};
    unsigned char sequence[] = "123456789";
    runTestSet(simple, sizeof(simple));
    runTestSet(sequence, sizeof(sequence));
    return 0;
}

我看到,我没有说出我的用例这一点。
我有一个系统的依赖,并需要使用不正确的(?)的Linux CRC。
我想在修剪的方式,可以让我做到这一点使用升压代替升压执行。

I see that i did not state my usecase for this. I have a System dependency and need to use the incorrect(?) Linux crc. I want to trim the boost implementation in a way that allows me to do this using boost instead.

我的机器上的输出是:

在这里输入的形象描述

推荐答案

更​​新 - 基于这些网站CRC计算器

update - based on these web site crc calculators

(CCITT选择(0xFFFF的))
http://www.lammertbies.nl/comm/info/crc-calculation.html

(choose ccitt(0xffff)) http://www.lammertbies.nl/comm/info/crc-calculation.html

(CRC选择CCITT)
http://www.zorc.breitbandkatze.de/crc.html

(choose crc ccitt) http://www.zorc.breitbandkatze.de/crc.html

这是调用此版本的CRC-16-CCITT假,也是第三个网站列出了其他的变化也被称为CCITT。

A third site that calls this version crc-16-ccitt-false, and also lists the other variations also called ccitt.

的http://复仇。 sourceforge.net/crc-catalogue/16.htm#crc.cat.crc-16-ccitt-false

在这种情况下,位不逆转。另外,9字节串123456789似乎是一个常见的​​测试。然而,其他的网站提到,CCITT一些版本的反转​​位作为Linux示例进行。我的猜测是使用哪一个将是协议/器件而定。至少现在你有逆转(Linux版)都和非反转(在$ C $在这个答案c)如果您需要切换。

In this case the bits are not reversed. Also the 9 byte string "123456789" seems like a common test. However other web sites mention that some versions of ccitt do reverse the bits as done in the linux example. My guess is that which one to use will be protocol / device specific. At least now you have both the reversed (linux) and non-reversed (the code in this answer) if you need to switch.

举例code补充说:

一个CRC是用一个N位多项式做比特串的伽罗瓦类型划分,产生N-1位余后的余数。在软盘的情况下,一个17位的多项式,0x11021用于产生一个16位的剩余部分。每个比特的逻辑是这样的:

A CRC is the remainder after doing a Galois type divide of a string of bits by a n bit polynomial, producing an n-1 bit remainder. In the case of a floppy disk, a 17 bit polynomial, 0x11021 is used to produce a 16 bit remainder. The logic for each bit goes something like this:

    crc << = 1;
    if(crc & 0x10000)crc ^= 0x11021;

此也可以被实现小号

    if(crc & 0x8000){crc = ((crc<<1) & 0xffff) & 0x1021;}
    else {crc = ((crc<<1) & 0xffff);}

举例code。这应该与升压code。

Example code. This should match the boost code.

typedef unsigned short u16;
typedef unsigned char u8;

u16 crctbl[256] = {
    0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,
    0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,
    0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6,
    0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,
    0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,
    0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d,
    0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4,
    0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,
    0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,
    0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b,
    0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
    0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,
    0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,
    0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49,
    0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,
    0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,
    0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f,
    0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067,
    0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,
    0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,
    0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d,
    0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
    0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,
    0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634,
    0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab,
    0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,
    0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,
    0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92,
    0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9,
    0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,
    0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,
    0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0};

u16 gencrc(u8 *bfr, size_t len)
{
u16 crc = 0xffff;
    while(len--)
        crc = (crc << 8) ^ crctbl[(crc >> 8)^*bfr++];
    return(crc);
}

int main()
{
u16 crc;
u8 a[4]  = {0x80, 0, 0, 0};
u8 b[10] = {"123456789"};
    crc = gencrc(a, 1);   // returns 0x7078
    crc = gencrc(b, 9);   // returns 0x29b1
    return(0);
}

这篇关于差异升压CRC和linux / lib目录/ CRC-ccitt.c的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆