- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在过去的几天里,我一直在努力了解 CRC 的工作原理。我坚持建议实现的特定优化。
我的理解:
*CRC 是多项式除法,其中位表示 x 的幂。我可以进行除法(使用正则多项式除法或使用位)并正确获取 CRC。
*移位寄存器用于保存余数。它是 n 位(对于 n 次多项式),因为每次减法最多影响 n 位。一旦整个消息被送入寄存器,它就会包含除法余数。
我卡住的地方:
在这个页面上: http://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks实现部分有一些伪代码。我对第一个伪代码和它的两个问题很好(尽管第一个很容易解决)。我无法理解第二个,以及 xor 的结合性/交换性如何帮助。通过手动操作,我看到第二个伪代码有效,但为什么呢?
其他来源:其他几篇文章给出了相同的优化(将位输入寄存器的左侧而不是右侧)。特别是这篇文章: http://www.ross.net/crc/download/crc_v3.txt在第 10 节中这样做(文本搜索单词 mangled)。除了这是用 table 做的,我还没有准备好 table !它确实说最后的 n 次迭代仅用于将消息的尾部放在寄存器的左侧,我理解这一点,但我还是无法理解这里的优化。
编辑:我找到了另一个引用资料(第 8 页): http://www.hackersdelight.org/crc.pdf但这仍然无济于事。它说预乘与后乘相同,但我不明白这是怎么回事,因为当在寄存器左侧找到 1 位时,这会改变寄存器中的位(触发减法)。
谢谢。感谢您对我的好奇心的帮助!
丹
最佳答案
在第一个伪代码中,余数用输入位串的前导部分初始化。然后在迭代过程中,在每一步中,余数都被向上移动,现在空出的底部位被输入位串中的下一位填充。要完成操作,输入位串需要附加零。这些零将在计算期间通过余数有效地清除数据。
在第二个伪代码中,余数一开始是清零的(全是零)。在迭代期间,输入位串中的下一位直接放在余数中的顶部位置。因此,完成计算不需要初始化和刷新。此外,对高位测试和余数操作的上移进行了重新排序。
您可以通过以下几个转换步骤将第一个伪代码算法转换为第二个伪代码算法。
从基本算法的伪代码开始(代码片段1):
function crc(bit array bitString[1..len], int len) {
remainderPolynomial := polynomialForm(bitString[1..n]) // First n bits of the message
for i from 1 to len {
remainderPolynomial := remainderPolynomial * x + bitString[i+n] * x0 // Define bitString[k]=0 for k>len
if coefficient of xn of remainderPolynomial = 1 {
remainderPolynomial := remainderPolynomial xor generatorPolynomial
}
}
return remainderPolynomial
}
第一个转换是交换更新余数多项式和测试最高位的顺序,即我们可以测试第二个最高位(在上移之前),然后在 if
分支更新在与生成多项式进行异或之前的余数,并添加 else
分支,该分支也会更新余数(如果最高位为零)。此外,请注意,余数的更新本质上是将其上移,然后将空的底部位设置为输入位串的下一位。所以 +
操作基本上是在执行 0 + ?
,这相当于 0 xor ?
。通过应用这些原则,我们现在得到以下等效伪代码:
function crc(bit array bitString[1..len], int len) {
remainderPolynomial := polynomialForm(bitString[1..n]) // First n bits of the message
for i from 1 to len {
if coefficient of xn-1 of remainderPolynomial = 1 {
remainderPolynomial := (remainderPolynomial * x xor bitString[i+n] * x0) xor generatorPolynomial
} else {
remainderPolynomial := remainderPolynomial * x xor bitString[i+n] * x0
}
}
return remainderPolynomial
}
现在,请注意在循环中我们将 bitString[i+n]
放在 x0
位置。然后该位在后续计算期间向上移动。我们可以在概念上将 bitString[i+n] * x0
更改为 bitString[i] * xn
。如果我们将它从 if/else
分支中取出并在向上移动余数 (... * x
) 之前执行此操作,我们将得到 .. . xor bitString[i] * xn-1
.并且因为我们现在将输入位串中的位放在余数的顶部,所以我们只需清除开头的余数,不需要附加零来通过余数寄存器清除数据。瞧,我们现在有了修改后的算法的伪代码(代码片段 2):
function crc(bit array bitString[1..len], int len) {
remainderPolynomial := 0
for i from 1 to len {
remainderPolynomial := remainderPolynomial xor (bitstring[i] * xn-1)
if (coefficient of xn-1 of remainderPolynomial) = 1 {
remainderPolynomial := (remainderPolynomial * x) xor generatorPolynomial
} else {
remainderPolynomial := remainderPolynomial * x
}
}
return remainderPolynomial
}
关于CRC(循环冗余校验)理解优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20917193/
我已经搜索过,但无法找到有关它是什么以及如何计算的信息。 我不知道为什么这个问题被否决了。不是说清楚和编程有关吗?或者我应该问: # 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 这是一个说明问
我是一名优秀的程序员,十分优秀!