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