-->

最终CRC对C(definitive CRC for C)

2019-07-20 20:02发布

由于CRC的用途很广泛,我很惊讶,由具有很难找到CRC实现在C.

是否有一个“明确的” CRC计算片段/对于C算法,即“每个人”使用? 或者:是有一个很好的实现CRC人可以担保,并指向我往? 我在寻找特别CRC8和CRC16实现。

试想想起来了,我的情况可能会有点标新立异。 我写的C代码的Linux,和代码应最终被移植到微控制器。 这似乎有些微的API做出来CRC的实现; 在任何情况下,我在寻找一个通用的软件实现(我读了CRC最初意思是硬件实现)。

Answer 1:

号没有“明确的CRC”作为CRC表示一组基于多项式算法。 各种[暧昧]通用名是基于尺寸通常给予(例如CRC-8,CRC-32)。 不幸的是,有几种不同版本的大多数尺寸。

维基百科的循环冗余校验项列出了一些常见的变体,但必须使用,否则会出现不兼容的定域 正确校验 。 (见我小李的答案是多么混乱这个可以发表评论!)

总之,挑选合适的实施和使用它 - 不存在,可以在网上找到例子举不胜举。 如果恰好是提供一个合适的实现,那么图书馆,通过各种手段,使用它。 然而,这没有“标准” C库。

这里有一些资源:

  • 一个“CRC16”(CRC16-CCITT)上AutomationWiki实施。
  • 实施CCITT循环冗余校验的多布斯医生。
  • 在IEEE 802.3循环冗余校验由克里斯·博雷利文章讨论了一个过时的赛灵思工具生成的Verilog(即“硬件”)的实施。
  • 请参阅相关的问题CRC32 C或C ++实现 -注意,有些答案涉及到“CRC32”(IEEE 802.3)和其他阿德勒-32 。
  • 该librock库, 提高 ,源校验和从GNU核心utils的..


Answer 2:

它不应该是很难找到CRC实现在C.你可以找到一个比较复杂的实现CRC-32的zlib的 。

这里有几个定义16位和8位的CRC ,它使用的约定在这个优秀的介绍的CRC 。

下面是一个简单的执行CRC-8的:

// 8-bit CRC using the polynomial x^8+x^6+x^3+x^2+1, 0x14D.
// Chosen based on Koopman, et al. (0xA6 in his notation = 0x14D >> 1):
// http://www.ece.cmu.edu/~koopman/roses/dsn04/koopman04_crc_poly_embedded.pdf
//
// This implementation is reflected, processing the least-significant bit of the
// input first, has an initial CRC register value of 0xff, and exclusive-or's
// the final register value with 0xff. As a result the CRC of an empty string,
// and therefore the initial CRC value, is zero.
//
// The standard description of this CRC is:
// width=8 poly=0x4d init=0xff refin=true refout=true xorout=0xff check=0xd8
// name="CRC-8/KOOP"

static unsigned char const crc8_table[] = {
    0xea, 0xd4, 0x96, 0xa8, 0x12, 0x2c, 0x6e, 0x50, 0x7f, 0x41, 0x03, 0x3d,
    0x87, 0xb9, 0xfb, 0xc5, 0xa5, 0x9b, 0xd9, 0xe7, 0x5d, 0x63, 0x21, 0x1f,
    0x30, 0x0e, 0x4c, 0x72, 0xc8, 0xf6, 0xb4, 0x8a, 0x74, 0x4a, 0x08, 0x36,
    0x8c, 0xb2, 0xf0, 0xce, 0xe1, 0xdf, 0x9d, 0xa3, 0x19, 0x27, 0x65, 0x5b,
    0x3b, 0x05, 0x47, 0x79, 0xc3, 0xfd, 0xbf, 0x81, 0xae, 0x90, 0xd2, 0xec,
    0x56, 0x68, 0x2a, 0x14, 0xb3, 0x8d, 0xcf, 0xf1, 0x4b, 0x75, 0x37, 0x09,
    0x26, 0x18, 0x5a, 0x64, 0xde, 0xe0, 0xa2, 0x9c, 0xfc, 0xc2, 0x80, 0xbe,
    0x04, 0x3a, 0x78, 0x46, 0x69, 0x57, 0x15, 0x2b, 0x91, 0xaf, 0xed, 0xd3,
    0x2d, 0x13, 0x51, 0x6f, 0xd5, 0xeb, 0xa9, 0x97, 0xb8, 0x86, 0xc4, 0xfa,
    0x40, 0x7e, 0x3c, 0x02, 0x62, 0x5c, 0x1e, 0x20, 0x9a, 0xa4, 0xe6, 0xd8,
    0xf7, 0xc9, 0x8b, 0xb5, 0x0f, 0x31, 0x73, 0x4d, 0x58, 0x66, 0x24, 0x1a,
    0xa0, 0x9e, 0xdc, 0xe2, 0xcd, 0xf3, 0xb1, 0x8f, 0x35, 0x0b, 0x49, 0x77,
    0x17, 0x29, 0x6b, 0x55, 0xef, 0xd1, 0x93, 0xad, 0x82, 0xbc, 0xfe, 0xc0,
    0x7a, 0x44, 0x06, 0x38, 0xc6, 0xf8, 0xba, 0x84, 0x3e, 0x00, 0x42, 0x7c,
    0x53, 0x6d, 0x2f, 0x11, 0xab, 0x95, 0xd7, 0xe9, 0x89, 0xb7, 0xf5, 0xcb,
    0x71, 0x4f, 0x0d, 0x33, 0x1c, 0x22, 0x60, 0x5e, 0xe4, 0xda, 0x98, 0xa6,
    0x01, 0x3f, 0x7d, 0x43, 0xf9, 0xc7, 0x85, 0xbb, 0x94, 0xaa, 0xe8, 0xd6,
    0x6c, 0x52, 0x10, 0x2e, 0x4e, 0x70, 0x32, 0x0c, 0xb6, 0x88, 0xca, 0xf4,
    0xdb, 0xe5, 0xa7, 0x99, 0x23, 0x1d, 0x5f, 0x61, 0x9f, 0xa1, 0xe3, 0xdd,
    0x67, 0x59, 0x1b, 0x25, 0x0a, 0x34, 0x76, 0x48, 0xf2, 0xcc, 0x8e, 0xb0,
    0xd0, 0xee, 0xac, 0x92, 0x28, 0x16, 0x54, 0x6a, 0x45, 0x7b, 0x39, 0x07,
    0xbd, 0x83, 0xc1, 0xff};

#include <stddef.h>

// Return the CRC-8 of data[0..len-1] applied to the seed crc. This permits the
// calculation of a CRC a chunk at a time, using the previously returned value
// for the next seed. If data is NULL, then return the initial seed. See the
// test code for an example of the proper usage.
unsigned crc8(unsigned crc, unsigned char const *data, size_t len)
{
    if (data == NULL)
        return 0;
    crc &= 0xff;
    unsigned char const *end = data + len;
    while (data < end)
        crc = crc8_table[crc ^ *data++];
    return crc;
}

// crc8_slow() is an equivalent bit-wise implementation of crc8() that does not
// need a table, and which can be used to generate crc8_table[]. Entry k in the
// table is the CRC-8 of the single byte k, with an initial crc value of zero.
// 0xb2 is the bit reflection of 0x4d, the polynomial coefficients below x^8.
unsigned crc8_slow(unsigned crc, unsigned char const *data, size_t len)
{
    if (data == NULL)
        return 0;
    crc = ~crc & 0xff;
    while (len--) {
        crc ^= *data++;
        for (unsigned k = 0; k < 8; k++)
            crc = crc & 1 ? (crc >> 1) ^ 0xb2 : crc >> 1;
    }
    return crc ^ 0xff;
}

#ifdef TEST
#include <stdio.h>
#define CHUNK 16384

int main(void) {
    unsigned char buf[CHUNK];
    unsigned crc = crc8(0, NULL, 0);
    size_t len;
    do {
        len = fread(buf, 1, CHUNK, stdin);
        crc = crc8(crc, buf, len);
    } while (len == CHUNK);
    printf("%#02x\n", crc);
    return 0;
}
#endif


Answer 3:

不知道CRC-8或CRC-16,但例如CRC-32码在RFC 1952 。 此RFC还引用了V.42标准,该标准描述了CRC-16在第8.1.1.6。

RFC 1952年还指出:

  If FHCRC is set, a CRC16 for the gzip header is present, immediately before the compressed data. The CRC16 consists of the two least significant bytes of the CRC32 for all bytes of the gzip header up to and not including the CRC16. [The FHCRC bit was never set by versions of gzip up to 1.2.4, even though it was documented with a different meaning in gzip 1.2.4.] 

因此,有你的CRC-16和CRC-32,潜在的。 (只取CRC-32,即的两个最低显著字节)。



Answer 4:

还有的用来实现不同的CRC算法数量。 还有就是幼稚一个没有多项式师。

这里是一个链接,各种算法,在C,通用32位CRC计算。 作者还给出了一些速度比较。

库普曼有一个网站给各个CRC的表演,以及为指导,以最好的CRC对于一个给定的数据包长度。



文章来源: definitive CRC for C
标签: c crc