CRC32 校验和是如何计算的?

2023-12-30

也许我只是没有看到它,但 CRC32 似乎要么不必要地复杂,要么在我可以在网络上找到的任何地方都没有得到充分的解释。

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

我读了CRC 错误检测算法的轻松指南 http://www.ross.net/crc/crcpaper.html,我必须说这并不是无痛的。它很好地阐述了这个理论,但作者从来没有得出一个简单的“就是这样”。他确实说明了标准 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;
}

但这似乎生成的值与我在互联网其他地方找到的值不一致。我could使用我在网上找到的值,但我想了解它们是如何创建的。

任何有助于澄清这些令人难以置信的令人困惑的数字的帮助都是very赞赏。


CRC32 的多项式为:

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

  • 维基百科 http://en.wikipedia.org/wiki/Cyclic_redundancy_check#CRCs_and_data_integrity
  • CRC计算 http://www.lammertbies.nl/comm/info/crc-calculation.html

或者以十六进制和二进制表示:

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

The highest term (x32) is usually not explicitly written, so it can instead be represented in hex just as

0x 04 C1 1D B7

随意数一下 1 和 0,但您会发现它们与多项式匹配,其中1是位 0(或第一位)并且x是位 1(或第二位)。

为什么是这个多项式?因为需要有一个给定多项式的标准,而该标准是由 IEEE 802.3 制定的。此外,找到有效检测不同比特错误的多项式也是极其困难的。

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

  • CRC 入门,第 5 章 http://chrisballance.com/wp-content/uploads/2015/10/CRC-Primer.html

为了更好地理解它,请考虑这个乘法:

(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
  • CRC 引物 Chp.5 http://chrisballance.com/wp-content/uploads/2015/10/CRC-Primer.html

为什么?因为 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 算术将增强消息除以 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。

  • CRC 入门,第 7 章 http://chrisballance.com/wp-content/uploads/2015/10/CRC-Primer.html

仅使用 32 位数字作为除数,并使用整个流作为除数。去掉商并保留余数。将剩余部分粘贴到消息末尾,您就得到了 CRC32。

一般人评价:

         QUOTIENT
        ----------
DIVISOR ) DIVIDEND
                 = REMAINDER
  1. 取前 32 位。
  2. 移位位
  3. 如果 32 位小于 DIVISOR,则转至步骤 2。
  4. 通过除法器对 32 位进行异或。转到步骤 2。

(请注意,流必须可被 32 位整除,否则应进行填充。例如,必须填充 8 位 ANSI 流。此外,在流末尾,除法也会停止。)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CRC32 校验和是如何计算的? 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • 没有特殊字符的密码验证器

    我是 RegEx 的新手 已经进行了大量搜索 但没有找到任何具体内容 我正在编写一个验证密码字符串的正则表达式 可接受的字符串必须至少具有 4 种字符类型中的 3 种 数字 小写字母 大写字母 特殊字符 我对包含有一个想法 也就是说 如果这
  • 根据属性的类型使用文本框或复选框

    如果我有这样的结构 public class Parent public string Name get set public List
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • std::vector 与 std::stack

    有什么区别std vector and std stack 显然 向量可以删除集合中的项目 尽管比列表慢得多 而堆栈被构建为仅后进先出的集合 然而 堆栈对于最终物品操作是否更快 它是链表还是动态重新分配的数组 我找不到关于堆栈的太多信息 但
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 评估 CRC-32 实现中的差异

    我见过相同基本 CRC 32 算法的许多不同实现 如下所示 int remain int sbox SIZESBOX int dividend int bit for dividend 0 dividend lt SIZESBOX divi
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 如何删除从网络服务返回的无法识别的字符?

    我正在开发一个调用休息网络服务的应用程序 有时 xml 响应包含电话无法显示的字符 显示这些字符时 会显示一个空框 我想过滤掉这些字符 如何检测某个字符是否能够显示在屏幕上 一些具体字符包括 http www fileformat info
  • iPhone Obj C -- 对可变字典数组进行排序 -- 显示字符串但按值排序

    我有一个 NSMutableArray 里面有 30 个字典 每个都包含一个名称和一个值 我目前已对名称进行排序 以便按字母顺序显示在表格视图中 但是 我想制作一个 UIButton 来提供仍然显示名称的选项 但按值排序 该值不需要显示 另
  • 从 TCP 套接字解析 XML 流

    我编写了一个 Ruby 脚本来通过 TCP 套接字连接到 XML 流 我想使用 LibXML 解析此 XML 流 我的问题是我不知道如何将此流传递给 LibXML 来自 LibXML 文档XML Document io io http li
  • 如何并排显示两个 Markdown 代码块

    我想并排显示源代码的两个块 重构之前和之后 是否可以并排创建两个代码块 如果不是那么替代解决方案是什么 无法使用纯 Markdown 语法在单个表格单元格中创建多行代码块 但您可以使用逐字 HTML 来完成此操作 下面是一个带有并排代码的两
  • Matplotlib 子图:imshow + 绘图

    我想创建一个如下图所示的图 图中有两个独特的情节 img1是使用生成的plt imshow while img2是使用生成的plt plot 下面提供了我用来生成每个图的代码 plt clf plt imshow my matrix plt
  • 带有输入组的引导面板

    我想做的是有一个引导面板 其左侧有一个按钮 右侧有一个按钮 有点像输入组 我希望这是有意义的 请原谅我的绘画技巧 但我想我应该附上一个例子来说明我的意思 面板可能不是最好的选择 所以如果有任何其他建议 请随时告诉我 Thanks 尝试这个c
  • MSBuild 和 TeamBuild - BuildInParallel 由于 MSB3021 文件权限冲突而失败

    我维护着一个相当大的软件的构建 其中包含大约 350 个 csharp 项目 我们的调试构建时间约为 17 分钟 我一直在寻找缩短构建时间的方法 BuildInParallel 属性确实看起来很有趣 特别是因为我们有一个四核服务器来进行构建
  • cordova - 多个 dex 文件定义 Lcom/google/android/gms/iid/zzc

    我正在尝试编译适用于 Android 的 cordova 应用程序 但收到此错误 有任何想法吗 这是我收到的错误 FAILURE Build failed with an exception What went wrong Executio
  • 如何对多态向量中包含的元素进行拆箱?

    看完之后这是 属于特征的对象的向量 的答案 https stackoverflow com a 25819164 129805 看起来 Rust 会自动拆箱 是这样吗 我的代码无法编译 我不明白该答案的代码如何编译 对包含装箱特征的多态向量
  • 如何查看Boto3 HTTPS请求字符串

    我已经能够查看 botocore 发送的PreparedRequest 的属性 但我想知道如何查看发送到AWS 的确切请求字符串 我需要确切的请求字符串才能将其与我正在测试 AWS 调用的另一个应用程序进行比较 您还可以在 boto3 中启
  • 如何组合和验证 swt 对话框的两个文本字段?

    我有另一个问题 我使用一个文本字段的修改侦听器来激活和停用 swt 对话框中的 确定 按钮 效果很好 现在我想为另一个文本字段添加修改侦听器 我希望仅当两个文本字段中都至少有一个字符时才激活 确定 按钮 这是两个字段的代码 descript
  • 如何验证 ADFS SAML 令牌

    我目前正在从 ADFS 生成 SAML 令牌 如下所示 WSTrustChannelFactory factory null try use a UserName Trust Binding for username authenticat
  • 如何在 Heroku 上使用 Datomic Pro?

    我想在 Heroku 上使用 Datomic Pro 目前为入门版 但我不想将我的下载密钥提交到 Git 中 相反 正确的做法似乎是将其存储在环境变量中 这意味着我的project clj现在包含 dependencies org cloj
  • 在 inversifyjs 中重置作用域容器

    我正在实现一个范围容器架构 这样一个新的container为每个 Express 请求 或 apollographql 请求 创建 我有一个生命周期方法 可以在发送完响应后调用 这有利于清理和释放内存 并且该方法可以引用我们已完成服务的请求
  • 我们可以在Java中调用带有空对象的静态方法吗?如果是这样,怎么办?

    既然静态方法可以直接从类中调用 即ClassName methodName 为什么需要用类的对象来调用静态方法呢 如果有人知道的话 请举例说明 public static void methodA 以下代码包含一个示例 其中通过null参考
  • 为什么我的通用 StatefulWidget 类在运行时会出现 TypeError?

    我有一个通用的StatefulWidget类有一个Function打回来 当我尝试调用该回调时 我得到一个运行时TypeError EXCEPTION CAUGHT BY WIDGETS LIBRARY The following Type
  • Tomcat 中的共享 JNI 库 (.so) - UnsatisfiedLinkError

    我有一个在 Tomcat7 中部署的两个 Web 应用程序之间共享的 JNI 库 so 我在正在部署的第一个 Web 应用程序中仅使用 System loadLibrary 加载一次库 然后在第二个应用程序中检查它是否已加载以不再加载 我尝
  • 活动与片段生命周期[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在开发我正在使用的新应用程序Activity and Fragment 他们之间有什么主要区别吗 Update 我在 Androi
  • 我可以使用 asyncio 读取和写入 multiprocessing.Pipe 吗?

    我需要在 Python 中的进程之间进行通信并且正在使用asyncio在每个进程中进行并发网络IO 目前我正在使用multiprocessing Pipe to send and recv进程之间存在大量数据 但是我在外部这样做asynci
  • CRC32 校验和是如何计算的?

    也许我只是没有看到它 但 CRC32 似乎要么不必要地复杂 要么在我可以在网络上找到的任何地方都没有得到充分的解释 我知道它是消息值的基于非进位的算术除法除以 生成器 多项式的余数 但它的实际实现让我无法理解 我读了CRC 错误检测算法的轻