CRC-32 计算器 - 文本、十六进制与文件校验和
CRC-32 校验和计算器
计算哈希前先按 UTF-8 编码。 6 字节
| 消息长度 | 6 字节 |
| CRC-32 | 0xFF55531A |
| CRC-32b(末尾补零字节) | 0x2F9F43A4 |
CRC-32 用于发现 zip 压缩包、gzip 流、PNG 数据块和以太网帧中的意外损坏。它不是加密哈希:它是线性的,很容易被伪造,因此绝不能用于防范对手的完整性校验。
功能介绍
校验和是一段长消息的短摘要,它的计算方式经过设计,使得消息中任何一处意外改动都极有可能同时改变这个摘要。这个概念比个人电脑早得多。上世纪五十年代 IBM 制造读打孔卡片的制表机,操作人员发现机器之间传输的数据偶尔会莫名其妙出错,原因可能是某列打歪了、卡片弯折了或者读卡器磨损了。工程上的解法是在传输数据的同时附带一个冗余的算术值,接收端重新算一遍再比对;对上了就认为传输完好,对不上就请求重传。现代的循环冗余校验正是这个思路的延续。CRC 把消息看成 GF(2) 上的多项式——在这个域里加法和减法都是异或——然后用它去除以一个固定的生成多项式,取余数作为校验值。CRC-32 使用的生成多项式是 0x04C11DB7,而由于位反转的形式在硬件和软件里实现起来便宜得多,实际代码用的常量是反转后的 0xEDB88320。常见实现会预先算出一张 256 项的查找表,每个字节只做一次查表加一次移位:crc = table[(crc 异或 字节) 与 0xFF] 异或 (crc 右移 8 位),这也是为什么一兆字节的数据只要几毫秒就能算完;而从定义出发生成这张表,比直接粘贴一串神奇数组更可靠,因为它排除了代码与它声称实现的规范脱节的可能。寄存器在处理第一个字节之前会被初始化为 0xFFFFFFFF,输出前再与 0xFFFFFFFF 异或一次,这一步叫作增广。两个异或都不是装饰。种子取零时,开头的零字节不会改变寄存器状态,于是 00 00 41 与 41 会得到完全相同的校验值;用全一初始化能强制把这些字节吸收进去,这正是连续零字节也能被检出的原因。最后那次异或保证了「消息加上它自己的校验值(按小端追加)」会得到固定余数 0x2144DF1C,接收端正是靠检查这个余数来判断通过,也正因为如此,空消息的 CRC 才会是整洁的 0x00000000 而不是一串一。CRC-32 与 CRC-32b 是同一算法的不同封装:本工具给出的 CRC-32b 是在你的数据后面追加一个 0x00 字节再计算,某些协议用这种方式区分载荷和它的结束标记;不过这个词在业界用得并不统一,通常所说的 BZIP2 变体(以字符串 123456789 的校验值 0xCBF43926 为标志)追加的是四个零字节,是另一个函数,所以在对接具体工具或格式时,务必确认它的实现到底追加了几个零字节。实际使用中,CRC-32 出现在几乎所有地方:每个 ZIP 条目、每个 gzip 和 zlib 压缩流的尾部、PNG 文件里的每一个数据块、MPEG-2 传输流的每个包,以及每一个以太网帧里的帧校验序列 FCS。但必须说清楚,CRC-32 绝不是密码学哈希。它是 GF(2) 上的线性函数:把同一个差值异或进两条等长消息,两者的校验值就会异或出同一个差值,也就是说,知道一条消息及其校验值的人,可以据此构造出另一条只差四个字节、却拥有任意校验值的消息,这种伪造不需要任何聪明才智甚至不需要搜索。CRC-32 还只有 32 位宽,按生日悖论,大约在 65536 条消息左右就会出现两条不同消息撞到同一个校验值。所以用它来发现意外损坏完全够用,用来抵御蓄意攻击则完全不够。
使用方法
- 在浏览器里打开 CRC-32 计算器。校验值由本机 JavaScript 现场算出,你输入的文字和选择的文件不会上传到任何服务器。
- 用顶部的三个按钮选择输入模式:Text 处理字符串,Hex bytes 处理原始二进制字节,File 直接校验整个文件。
- 在 Text 模式下,把内容填进「Input text」输入框。工具会先做 UTF-8 编码,所以带中文或表情符号的内容字节数会明显变多,下方会实时显示字节数。
- 在 Hex 模式下,粘贴成对的十六进制数字,例如 48 65 6c 6c 6f。空格、逗号和 0x 前缀会被自动去掉,位数是奇数会直接报错,出现非十六进制字符也会提示而不是悄悄忽略。
- 在 File 模式下,用「Choose a file」控件选择文件。工具通过浏览器的 File API 读取,并同时显示磁盘上的文件大小和实际参与计算的字节数。
- 在 Output format 下拉菜单里选择需要的表示形式:Hex、Decimal、Octal、Binary 或 Base64,CRC-32 结果框会立即按所选格式重新渲染。
- 查看下方汇总表里的消息字节长度、CRC-32 值,以及追加一个零字节后的 CRC-32b 值,方便你与其他协议的定义比对。
- 把得到的值和发布方或传输系统记录的校验值对照,即可确认下载、上传或传输的内容是否完好。
计算示例
输入: Text 模式,输入字符串 CRC-32
过程:
6 个 UTF-8 字节 43 52 43 2D 33 32 逐字节通过查表循环结果: CRC-32 = 0xFF55531A;末尾追加一个零字节的 CRC-32b = 0x2F9F43A4
输入: Text 模式,输入字符串 123456789
过程:
这是 ISO 3309 与 ITU-T V.42 为 CRC-32/BZIP2 规定的标准校验字符串结果: 0xCBF43926 —— 如果你的实现结果不同,说明参数选错了
输入: Hex 模式,输入字节 48 65 6c 6c 6f
过程:
五个原始字节,也就是 Hello,以十六进制而不是文本方式输入结果: 0xF7D18982 —— 与直接把单词 Hello 当文本计算的结果并不相同
输入: File 模式,选择一个长度为 0 的空文件
过程:
循环一次都没有执行,初始值直接穿过最后一次异或结果: 0x00000000,这也是空消息容易被认出来的原因
相关搜索
相关搜索:crc32计算器, 在线计算crc32, 文件校验和, 校验和工具, crc32校验, 字符串crc32。
crc32计算器在线计算crc32文件校验和校验和工具crc32校验字符串crc32十六进制crc32crc32b文件完整性校验校验和生成器crc算法crc32免费工具zip完整性校验gzip校验png数据块校验以太网帧校验crc32和sha256区别检测文件损坏下载文件校验异或校验
常见问题
CRC-32 在真实软件里到底用在哪里?
凡是「用极低成本确认内容没有意外损坏」比「提供安全保证」更值得的地方,都会出现 CRC-32。每个 ZIP 压缩包都把校验值存在中央目录里,解压时会逐条比对,文件被截断或发生位翻转时工具会明确报错,而不是悄悄解出一堆乱码。gzip 和 zlib 在压缩流末尾追加 CRC-32,这就是损坏的 .gz 文件会给出校验错误、而不是让人摸不着头脑的解压错误的原因。PNG 在每一个数据块里都存 CRC-32,既能单独验证每个块,也让解码器遇到第一个坏块就停下来。MPEG-2 传输流每个包带一个,以太网帧的帧校验序列(FCS)也是 CRC-32,通常由网卡硬件在每个经过交换机的帧上计算。这些场景的威胁模型是同一个:噪声、硬件衰减、部分写入和版本错乱,而不是有动机的攻击者。
CRC-32 是密码学哈希吗?能用它存密码吗?
不能,把它用来存密码或者校验来自不可信来源的下载都是严重的错误。CRC 是 GF(2) 上的线性函数,这意味着把同一个差值异或进两条消息,它们的校验值也会异或出同样的差值。任何知道一条消息及其校验值的人,都可以构造出另一条只差几个字节、却带着任意校验值的消息,整个过程既不需要巧妙的数学也不需要暴力搜索。CRC-32 只有 32 位宽,攻击者用显卡几秒钟就能为指定原文算出一个碰撞。它没有密钥、没有盐、没有工作量参数,也没有雪崩效应,因此完全不提供单向性、不可预测性和抗暴力破解能力,而密码存储和代码签名恰恰依赖这些性质。防范恶意篡改请使用 SHA-256 这类密码学哈希,存放任何与凭据相关的东西请使用 Argon2id 或 bcrypt 这类专用口令函数。
为什么 CRC-32b 的结果和 CRC-32 不一样?
因为这两个名字说的是同一个算法包在略微不同的封装里。本工具的 CRC-32b 一行是在你的数据后面追加一个 0x00 字节再跑同一套算法,多出来的这个字节会改变寄存器状态,于是所有结果都随之改变。这种变体的作用是区分载荷和它自己的结束标记,这样一条恰好以零字节结尾的数据流就不会和意外以零结尾的流搞混。值得知道的是,这个术语在业界用得很不统一:通常写作 CRC-32/BZIP2、并以字符串 123456789 得到 0xCBF43926 为标志的那个变体,追加的是四个零字节而不是一个,是完全不同的函数。如果你要和某个具体工具或格式对接,请直接查看它的实现追加了几个零字节,而不要相信名字。
常量 0xEDB88320 到底是什么意思?
它是 CRC-32 生成多项式 0x04C11DB7 的位反转形式,几乎出现在你遇到的所有 CRC-32 软件实现里。生成多项式定义了哪些比特模式会被当作错误。教科书上的标准写法是正向比特序,但反转之后整个计算可以从字节的高位往低位走,每个字节只需要一次查表加一次移位,而不是八次带条件的移位。在反射式实现里,0x04C11DB7 反转过来就是 0xEDB88320,而表中那 256 项是这样生成的:从一个字节值开始,对它执行八次「最低位为 1 就与 0xEDB88320 异或后右移,否则直接右移」的循环。像本工具这样从定义出发生成整张表,比直接粘贴一长串数组更稳妥,因为这样就杜绝了预置的表和它声称实现的规范之间发生偏差的可能。
为什么不同的文件有时会得到相同的 CRC-32?
因为输出空间只有 32 位,全部可能的校验值大约 42.9 亿个,却要由无穷多消息共享,必然有一部分消息撞在一起。用生日悖论估算,大约在 65536 条消息附近出现重复校验值就成了大概率事件,而真实文件的情况比随机数据更糟,因为结构化的文档通常只在少数几个可预测的位置上不同。这不是设计缺陷,恰恰是设计按预期工作的证据:CRC-32 能百分之百检出单比特错误以及 32 位以内的突发错误,这几乎覆盖了噪声、老化和传输故障造成的全部意外损坏。它做不到的是在攻击者面前证明身份,因为攻击者可以在几秒内刻意构造出碰撞。如果需要抗碰撞能力,就需要密码学哈希。
我怎么确认下载的文件没有被损坏?
在这里算出这个文件的 CRC-32,然后和发布方或传输系统记录的校验值比对,一致就说明文件完好无损。很多工具其实已经替你做了,因为 unzip 会校验每个条目,gzip 和 zlib 会校验流尾,浏览器在解码 PNG 时也会校验数据块;但自己动手算一次,是确认某个特定工具算出了什么结果最快的办法,在遇到没有内置校验的特殊格式时更是唯一办法。选择 File 模式,选中下载文件,读取「CRC-32 of file」的输出即可。有一点必须提醒:校验值一致能证明文件就是发布方生成的那个,前提是你信任发布方。如果下载过程可能被篡改,具备该能力的攻击者可以做出校验值相同的另一个文件——这正是 GPG 或 Sigstore 这类签名机制要出现在校验和之外的原因。
我的文件或文字会被上传到服务器吗?
不会。这是一个纯客户端组件:浏览器里的 JavaScript 读取你的文本、十六进制字节或者你选中的文件,在内存中构建 CRC-32 查找表并本地跑完校验循环。没有任何数据走网络,不会写进服务器日志,关闭标签页之后也不会留下痕迹。文件模式通过浏览器 File API 实现,按需从本地磁盘读入内存。这一点在实际使用中很有价值,而不只是隐私问题:你可以校验几 GB 的磁盘镜像或者受管制的机密归档,既不用等上传完,也不用把数据副本交给第三方服务。