Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何计算CRC32校验和?_C_Checksum_Crc32 - Fatal编程技术网

如何计算CRC32校验和?

如何计算CRC32校验和?,c,checksum,crc32,C,Checksum,Crc32,也许我只是看不到,但CRC32似乎不必要地复杂,或者在我能在网上找到的任何地方都没有得到充分的解释 我知道它是消息值的非进位算术除法的余数,除以(生成器)多项式,但我无法理解它的实际实现 我读过,我必须说这不是无痛的。它对理论进行了很好的阐述,但作者从未得到一个简单的“就是这样”。他确实说了标准CRC32算法的参数,但他忽略了清楚地说明如何实现它 让我感到困惑的是,当他说“就是这样”,然后又补充说,“哦,顺便说一下,它可以反转,或者从不同的初始条件开始”,并且没有给出一个明确的答案,说明在他刚刚

也许我只是看不到,但CRC32似乎不必要地复杂,或者在我能在网上找到的任何地方都没有得到充分的解释

我知道它是消息值的非进位算术除法的余数,除以(生成器)多项式,但我无法理解它的实际实现

我读过,我必须说这不是无痛的。它对理论进行了很好的阐述,但作者从未得到一个简单的“就是这样”。他确实说了标准CRC32算法的参数,但他忽略了清楚地说明如何实现它

让我感到困惑的是,当他说“就是这样”,然后又补充说,“哦,顺便说一下,它可以反转,或者从不同的初始条件开始”,并且没有给出一个明确的答案,说明在他刚刚添加的所有更改中,计算CRC32校验和的最终方法是什么

  • 对于如何计算CRC32,是否有更简单的解释
我试图用C编写表格的形成方式:

for (i = 0; i < 256; i++)
{
    temp = i;

    for (j = 0; j < 8; j++)
    {
        if (temp & 1)
        {
            temp >>= 1;
            temp ^= 0xEDB88320;
        }
        else {temp >>= 1;}
    }
    testcrc[i] = temp;
}
(i=0;i<256;i++)的

{
温度=i;
对于(j=0;j<8;j++)
{
如果(临时和1)
{
温度>>=1;
温度^=0xEDB88320;
}
else{temp>>=1;}
}
testcrc[i]=温度;
}
但这似乎产生了与我在互联网上其他地方发现的价值观不一致的价值观。我可以使用我在网上找到的值,但我想了解它们是如何创建的


任何有助于清除这些令人难以置信的混乱数字的帮助都将非常感激。

CRC非常简单;取一个表示为位和数据的多项式,然后将多项式分解为数据(或者将数据表示为多项式并执行相同的操作)。介于0和多项式之间的余数是CRC。您的代码有点难以理解,部分原因是它不完整:没有声明temp和testcrc,因此不清楚索引了什么,以及算法中运行了多少数据

理解CRC的方法是尝试使用一小段数据(16位左右)和一个短多项式计算一些CRC——可能是4位。如果您以这种方式练习,您将真正了解如何编写代码


如果您经常这样做,CRC在软件中的计算速度非常慢。硬件计算效率更高,只需要几个门。

CRC32的多项式为:

x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1

或十六进制和二进制:

0x 01 04 C1 1D B7
1 0000 0100 1100 0001 0001 1101 1011 0111

最高项(x32)通常不是显式编写的,因此它可以用十六进制表示,就像

0x 04 C1 1D B7

可以随意数一数1和0,但你会发现它们与多项式匹配,其中
1
是位0(或第一位),而
x
是位1(或第二位)

为什么是多项式?因为需要一个给定多项式的标准,而该标准是由IEEE 802.3设定的。此外,很难找到一个有效检测不同位错误的多项式

您可以将CRC-32看作是一系列“无进位的二进制算术”,或者基本上是“异或和移位运算”。这在技术上称为多项式算术

要更好地理解它,请考虑以下乘法:

(x^3 + x^2 + x^0)(x^3 + x^1 + x^0)
= (x^6 + x^4 + x^3
 + x^5 + x^3 + x^2
 + x^3 + x^1 + x^0)
= x^6 + x^5 + x^4 + 3*x^3 + x^2 + x^1 + x^0
如果我们假设x是基数2,那么我们得到:

x^7 + x^3 + x^2 + x^1 + x^0
为什么??因为3x^3是11x^11(但我们只需要1或0个前置数字),所以我们继续:

=1x^110 + 1x^101 + 1x^100          + 11x^11 + 1x^10 + 1x^1 + x^0
=1x^110 + 1x^101 + 1x^100 + 1x^100 + 1x^11 + 1x^10 + 1x^1 + x^0
=1x^110 + 1x^101 + 1x^101          + 1x^11 + 1x^10 + 1x^1 + x^0
=1x^110 + 1x^110                   + 1x^11 + 1x^10 + 1x^1 + x^0
=1x^111                            + 1x^11 + 1x^10 + 1x^1 + x^0
但是数学家们改变了规则,使之成为mod 2。所以基本上任何二元多项式mod 2都是加法,没有进位或异或。我们的原始方程如下所示:

=( 1x^110 + 1x^101 + 1x^100 + 11x^11 + 1x^10 + 1x^1 + x^0 ) MOD 2
=( 1x^110 + 1x^101 + 1x^100 +  1x^11 + 1x^10 + 1x^1 + x^0 )
= x^6 + x^5 + x^4 + 3*x^3 + x^2 + x^1 + x^0 (or that original number we had)
我知道这是一个信念的飞跃,但这超出了我作为一名直线程序员的能力。如果你是一名核心的计算机科学学生或工程师,我将挑战你打破这一点。每个人都将从这一分析中受益

因此,要制作一个完整的示例:

   Original message                : 1101011011
   Polynomial of (W)idth 4         :      10011
   Message after appending W zeros : 11010110110000
现在,我们使用CRC算法将增强消息除以多边形。这与之前的划分相同:

            1100001010 = Quotient (nobody cares about the quotient)
       _______________
10011 ) 11010110110000 = Augmented message (1101011011 + 0000)
=Poly   10011,,.,,....
        -----,,.,,....
         10011,.,,....
         10011,.,,....
         -----,.,,....
          00001.,,....
          00000.,,....
          -----.,,....
           00010,,....
           00000,,....
           -----,,....
            00101,....
            00000,....
            -----,....
             01011....
             00000....
             -----....
              10110...
              10011...
              -----...
               01010..
               00000..
               -----..
                10100.
                10011.
                -----.
                 01110
                 00000
                 -----
                  1110 = Remainder = THE CHECKSUM!!!!
除法产生一个商,我们丢弃它,和一个余数,它是计算出的校验和。计算到此结束。通常,校验和随后被附加到消息中,结果被传输。在这种情况下,传输为:11010111110

仅使用32位数字作为除数,并使用整个流作为红利。扔掉商,保留剩余的。把剩下的钉在留言的末尾,你就有了一个CRC32

普通人评论:

         QUOTIENT
        ----------
DIVISOR ) DIVIDEND
                 = REMAINDER
  • 以前32位为例
  • 移位位
  • 如果32位小于除数,则转至步骤2
  • 按除数异或32位。转至步骤2

  • (请注意,流必须被32位除法,否则它应该被填充。例如,一个8位的ANSI流必须被填充。同样在流的末尾,除法被停止。)

    除了维基百科和文章之外,我发现一篇题为*的论文是一个很好的参考

    基本上有三种计算CRC的方法:代数方法、面向位的方法和表驱动方法。在*中,这三种算法/方法中的每一种都在理论上进行了解释,并在附录中用C编程语言实现了CRC32

    *PDF链接
    反向CRC–理论与实践
    胡柏林公共报告
    SAR-PR-2006-05
    2006年5月
    作者:
    Martin Stigge、Henryk Plötz、Wolf Müller、Jens Peter Redlich

    对于IEEE802.3,CRC-32。将整个消息视为一个串行位流,在消息末尾附加32个零。接下来,您必须反转消息每个字节的位,并对前32位进行1的补码。现在,迪维