- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
也许我只是没有看到它,但 CRC32 似乎不必要地复杂,或者在我可以在网络上找到的任何地方都没有充分解释。
我知道它是消息值的非基于进位的算术除法除以(生成器)多项式的余数,但我不知道它的实际实现。
我读过 A Painless Guide To CRC Error Detection Algorithms ,我必须说这并非没有痛苦。它很好地阐述了这个理论,但作者从来没有说出一个简单的“就是这样”。他确实说明了标准 CRC32 算法的参数是什么,但他忽略了清楚地说明如何实现它。
让我理解的部分是当他说“就是这样”然后补充说“哦顺便说一下,它可以被逆转或从不同的初始条件开始”并且没有给出明确的答案考虑到他刚刚添加的所有更改,计算 CRC32 校验和的 final方法。
我试图用 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;
}
但这似乎生成的值与我在 Internet 其他地方找到的值不一致。我可以使用我在网上找到的值,但我想了解它们是如何创建的。
任何帮助清理这些令人难以置信的困惑数字的人都将非常感激。
最佳答案
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)
我知道这是一种信仰的飞跃,但这超出了我作为一名程序员的能力。如果您是 CS 的硬核学生或工程师,我挑战将其分解。每个人都会从这个分析中受益。
所以要制定一个完整的例子:
Original message : 1101011011
Polynomial of (W)idth 4 : 10011
Message after appending W zeros : 11010110110000
现在我们使用 CRC 算法将增强消息除以 Poly。这与之前的划分相同:
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!!!!
除法产生商(我们将其丢弃)和余数(计算的校验和)。至此结束计算。通常,校验和会附加到消息中并传输结果。在这种情况下,传输将是:11010110111110。
仅使用 32 位数字作为除数,并将整个流用作除数。去掉商,保留余数。将消息末尾的其余部分添加到 CRC32 中。
平均评价:
QUOTIENT
----------
DIVISOR ) DIVIDEND
= REMAINDER
(请注意,流必须可以除以 32 位,否则应该被填充。例如,必须填充 8 位 ANSI 流。同样在流的末尾,除法停止。)
关于c - 如何计算 CRC32 校验和?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2587766/
我已经搜索过,但无法找到有关它是什么以及如何计算的信息。 我不知道为什么这个问题被否决了。不是说清楚和编程有关吗?或者我应该问: # Or you can compute the running CR
如果我有一定数量的字节要串行传输,我如何确定使用哪个 CRC(CRC8、CRC16 等,基本上是多少位的 CRC?)并且错误检测百分比仍然很高?有这个公式吗? 最佳答案 从 CRC 长度的角度来看,适
这个问题在这里已经有了答案: Incremental Checksums (3 个答案) 关闭 8 年前。 如果我有子串 S0, S1, ... Sn 计算出的 CRCs C0, C1, ... C
我知道 CRC 是一个线性函数,这意味着 CRC(x xor y) = CRC(x) xor CRC(y),但我不知道如何证明 CRC 的这个属性。 有谁有想法吗? 非常感谢! 最佳答案 这通常不是真
我知道使用 CRC 的全部目的是进行错误检测,但我听说有人说除了错误检测之外,它还可以用来进行基本的错误纠正。我很好奇是否是这样,如果是这样,它有多强大?我的意思是,我们通常将 CRC 称为能够执行
我见过 8 位、16 位和 32 位 CRC。 在什么时候我需要跳转到更广泛的 CRC? 我的直觉 react 是它基于数据长度: 1-100 字节:8 位 CRC 101 - 1000 字节:16
我正在学习 CRC,搜索引擎和 SO 对此一无所知...... 为什么我们有“正态”、“逆向”和“倒数”多项式?是喜欢 Big Endian、Little Endian 还是其他什么? 最佳答案 CR
在学习计算机网络类(class)时,教授谈到了示例代码中两个有效代码字之间的汉明距离。我已经阅读了有关汉明距离的信息,从告诉 2 个字符串之间的差异距离的角度来看,这是有道理的。例如: Code Wo
我从Wikipedia知道CRC计算算法。关于RAR文件的结构我读过here 。例如有这样写: The file has the magic number of: 0x 52 61 72 21
我已经阅读了 CCITT 和 TI 关于 msp430 的文档。是否可以使用任何内置函数计算 MSP430F5438A 的 CRC?或者我是否必须为每个获取的数据计算 CRC。 最佳答案 可以使用软件
我尝试修改现有项目的 CRC 模块。目前它使用 CRC-16-CCITT。从代码中我知道它的多项式是0x11021,它的CRC-Table是: static const unsigned sh
使用线性反馈移位寄存器(LFSR)实现CRC生成有两种方法,如图所示。图中生成多项式的系数为100111,红色“+”圆圈为异或运算符。两者的初始化寄存器值都是 00000。 例如,如果输入数据比特流是
当数据长度不是4的倍数时,有没有办法通过表驱动的方式加快CRC校验过程?在我的问题中,有 226 位需要检查,并通过 CRC24Q 算法为此计算了 24 位校验和。 最佳答案 使用表格计算第一部分的c
我需要计算消息的 CRC 并将其放在该消息的开头,以便带有“前置”补丁字节的消息的最终 CRC 等于 0。我能够做到这在几篇文章的帮助下非常容易,但不适用于我的特定参数。问题是我必须使用给定的 CRC
我正在将一些从我自己的类中定义的对象保存到文件中。 (保存流数据)。 这一切都很好,但我希望能够在文件中存储该文件的 CRC 校验和。 然后,每当我的应用程序尝试打开文件时,它都可以读取内部存储的 C
我有一组受 16 位校验和保护的数据,需要更正。校验和位置是已知的,计算它们的确切区域以及用于计算它们的确切算法却未知。 16 位,最低有效位在前。我怀疑这是某种 16 位 CRC,但我无法找到实际计
我想使用Nucleo L053R8的crc计算单元计算3字节的CRC值。生成多项式如下:g(X)=x^24 + x^10 + x^9 + x^6 + x^4 + x^3 + x + 1 看来使用这个C
开始之前:我绝对是 JAVA 的初学者。我一直是一名 C++ 程序员。所以当我在这里做傻事时请告诉我! 我正在查询一个巨大的数据库并将该数据直接导出到一个 zip 文件中。我们在这里讨论的是 35GB
我有一些 C++ 代码,我正在将其移植到 C。当我在 C 代码中计算 CRC 时,出于某种原因,它返回错误的 CRC 值,而 C++ 代码运行良好。我是 C++ 的新手。我需要一些帮助来理解我在返回错
我有两个来源来计算看似相同的 crc 值。我不明白为什么“boost/crc.hpp”实现与“linux/lib/crc-ccitt.c”实现不同。 crc-ccitt.c boost 这是一个说明问
我是一名优秀的程序员,十分优秀!