使用方法
- 输入或粘贴文本;把输入格式切换为十六进制可以输入原始字节,也可以打开文件计算其内容的校验和。
- ZIP、gzip 和 PNG 使用默认的 CRC-32;iSCSI、ext4、Btrfs 和 Google Cloud Storage 请选择 CRC-32C。
- 选择输出格式:小写十六进制、大写十六进制、十进制或 Base64。
- 如需校验,把预期的校验和粘贴到“对比”框中,可以是十六进制(不带 0x)、十进制或 Base64。
什么是 CRC32 校验和
循环冗余校验(CRC)把输入看作一个很长的二进制多项式,用固定的生成多项式去除,并保留余数。CRC-32 的余数为 32 位,通常写成 8 个十六进制数字,或 0 到 4294967295 之间的无符号整数。对数据的几乎任何改动都会改变余数。
CRC 专门针对线缆、无线信道和磁盘中真实出现的错误而设计。CRC-32 能检测出所有长度不超过 32 位的突发错误,随机损坏未被发现的概率只有约 43 亿分之一。它的计算速度也非常快,因此被内置在 ZIP、gzip、PNG 和以太网帧中。
CRC-32 与 CRC-32C
| CRC-32 | CRC-32C(Castagnoli) | |
|---|---|---|
| 生成多项式 | 0x04C11DB7,反射形式 0xEDB88320 | 0x1EDC6F41,反射形式 0x82F63B78 |
123456789 的校验值 | cbf43926 | e3069283 |
| 使用场景 | ZIP、gzip、PNG、以太网 | iSCSI、SCTP、ext4 元数据、Btrfs、Google Cloud Storage |
| 硬件支持 | ARMv8 CRC32 指令 | x86 SSE4.2 的 crc32 指令、ARMv8 |
两者的初始值都是 0xFFFFFFFF,都按每个字节的最低位优先处理,并在最后取反,区别只在生成多项式,所以同一份数据会得到两个毫不相关的结果。前者就是大多数工具所说的“CRC32”,在 CRC 参数目录中称为 CRC-32/ISO-HDLC;CRC-32C 出现得更晚,因检错能力更强而被存储和网络协议采用。Google Cloud Storage 提供 CRC-32C,Amazon S3 两种都支持,它们都把校验和表示为 4 个字节按大端序排列后的 Base64,与本工具的 Base64 输出完全一致。
校验和不等于安全校验
CRC 防的是意外,而不是攻击。它是线性函数,任何人都可以在修改文件后再调整其中 4 个字节,让 CRC-32 保持不变。因此,CRC 一致并不能排除有人故意篡改。校验下载文件时,应与可信来源提供的 SHA-256 哈希进行比较;需要证明消息由谁发出时,请使用 HMAC。
32 位用来标识数据也太短了。在大约 7.7 万个随机文件中,出现两个文件 CRC-32 相同的概率就已经达到 50%,所以不要把它当作唯一 ID 或去重依据。在不涉及攻击者的场景下,MD5 或 SHA-256 是好得多的数据指纹。
在代码中计算 CRC32
# Python:Python 3 中 zlib.crc32 返回无符号整数,
# 只有兼容 Python 2 时才需要 "& 0xffffffff"
import zlib
format(zlib.crc32(b'123456789'), '08x') # 'cbf43926'
// Node.js 20.15+ 和 22.2+
require('zlib').crc32('123456789').toString(16).padStart(8, '0') // 'cbf43926'
// Go (import "hash/crc32")
crc32.ChecksumIEEE(data) // CRC-32
crc32.Checksum(data, crc32.MakeTable(crc32.Castagnoli)) // CRC-32C
// Java:java.util.zip.CRC32,Java 9 起还有 java.util.zip.CRC32C
// PHP
sprintf('%08x', crc32('123456789')); // 'cbf43926'
hash('crc32b', '123456789'); // 'cbf43926',同样是 CRC-32
hash('crc32c', '123456789'); // 'e3069283'
hash('crc32', '123456789'); // '181989fc',另一种 CRC
PHP 中要注意名称:名为 crc32 的哈希算法并不是 ZIP 使用的校验和,而是 bzip2 使用的 CRC,并且按相反的字节顺序输出。要与 ZIP、gzip 和本工具的结果一致,请使用 crc32b 或 crc32() 函数。Unix 的 cksum 命令又是另一种变体,还会把文件长度计算在内,所以结果同样对不上。
编码示例
| 输入 (UTF-8) | CRC-32 |
|---|---|
Hello, World! | ec4ac3d0 |
Base64.is | 915d7207 |
你好 | 50a2b841 |
常见问题
“123456789” 的 CRC32 是多少?
cbf43926(十进制 3421780262),CRC-32C 为 e3069283。如果你自己的实现得到这两个值,说明参数与本工具一致。为什么我的 CRC32 与其他工具算出的不一样?
cksum 的结果各不相同);输入字节(换行符、末尾多余的换行、文本编码);数字格式(有些语言返回有符号 32 位整数,较大的值会变成负数);以及字节顺序。为什么 ZIP 或 gzip 文件里的 CRC 字节是反的?
unzip -v 以及大多数程序都把最高位字节写在最前面。可以计算大文件的 CRC32 吗?
可以。点击“打开文件”,校验和会在你的设备上根据文件字节计算,文件不会上传;只要浏览器能把文件载入内存即可。之后可以与 SFV 校验文件或 ZIP 列表中的值进行比较。
CRC32 算哈希函数吗?
它能把任意长度的数据映射为固定的 32 位值,所以常与哈希函数放在一起,但它本质上是校验和:只能发现意外错误,无法防范有人故意修改数据。如果需要更可靠的数据指纹,结果下方的“全部算法”表格会同时列出同一输入的 MD5 和 SHA 系列哈希。