CRC32 对于不同的输入是一样的

CRC32 is the same for different inputs

剧情简介

我计算几个十六进制输入的 CRC32 使用:

http://www.sunshine2k.de/coding/javascript/crc/crc_js.html

和其他一些 CRC32 计算器。

问题

无论我输入什么,我都会得到相同的 CRC32:

aa aa 3 0 0 0 8 0 45 0 0 34 0 0 40 0 40 6 b7 e c0 a8 1 64 c0 a8 1 1 dd 95 0 50 f4 11 d8 cf 81 8e e5 e3 80 10 10 0 d6 4c 0 0 1 1 8 a f a7 bf e0 0 0 2a f9 da b3 91 bd

结果 CRC 值:0x2144DF1C

aa aa 3 0 0 0 86 dd 60 0 77 b0 1 49 11 ff fe 80 0 0 0 0 0 0 0 2 b9 df 87 1b 9a 36 ff 2 0 0 0 0 0 0 0 0 0 0 0 0 0 fb 14 e9 14 e9 1 49 36 d5 0 0 0 0 0 11 0 0 0 0 0 1 8 5f 61 69 72 70 6c 61 79 4 5f 74 63 70 5 6c 6f 63 61 6c 0 0 c 0 1 5 5f 72 61 6f 70 c0 15 0 c 0 1 8 5f 61 69 72 70 6f 72 74 c0 15 0 c 0 1 7 5f 75 73 63 61 6e 73 c0 15 0 c 0 1 8 5f 73 63 61 6e 6e 65 72 c0 15 0 c 0 1 6 5f 75 73 63 61 6e c0 15 0 c 0 1 7 5f 69 70 70 75 73 62 c0 15 0 c 0 1 4 5f 69 70 70 c0 15 0 c 0 1 5 5f 69 70 70 73 c0 15 0 c 0 1 8 5f 70 72 69 6e 74 65 72 c0 15 0 c 0 1 f 5f 70 64 6c 2d 64 61 74 61 73 74 72 65 61 6d c0 15 0 c 0 1 4 5f 70 74 70 c0 15 0 c 0 1 d 5f 61 70 70 6c 65 2d 6d 6f 62 64 65 76 c0 15 0 c 0 1 8 39 30 65 33 30 37 66 63 4 5f 73 75 62 e 5f 61 70 70 6c 65 2d 6d 6f 62 64 65 76 32 c0 15 0 c 0 1 f 5f 61 70 70 6c 65 2d 70 61 69 72 61 62 6c 65 c0 15 0 c 0 1 c0 e1 0 c 0 1 c 5f 73 6c 65 65 70 2d 70 72 6f 78 79 4 5f 75 64 70 c0 1a 0 c 0 1 0 0 29 5 a0 0 0 11 94 0 c 0 4 0 8 0 c e0 ac cb 92 66 48 c2 43 4c 9f

结果 CRC 值:0x2144DF1C

aa aa 3 0 0 0 8 0 45 0 0 34 0 0 40 0 40 6 b7 e c0 a8 1 64 c0 a8 1 1 dd 8f 0 50 f ff 68 34 80 1c a4 f9 80 10 10 10 73 b8 0 0 1 1 8 a f a7 ba c 0 0 2a 62 e1 2d 8a cd

结果 CRC 值:0x2144DF1C

问题

为什么会这样?

CRC32 的冲突并不少见。 CRC32是一种只使用32位的校验和算法。

应该使用校验和来验证数据的完整性。它不应用于创建唯一标识符。它基本上可用于检测数据传输错误。

如果需要查错,就用crc32。

如果您需要标识符,请使用 UUID。

如果您需要速度(而不是安全哈希),请尝试使用 64 位 xxHash。

如果您需要安全指纹,请考虑使用像 sha256 这样的加密散列。

您的所有示例输入都已经包含一个嵌入式 CRC32 值 - 您基本上是在验证该值,假设所有数据都有效,恒定结果正是您所期望的。该常数结果不为零,因为您计算 CRC 的数据多于所涵盖的嵌入式 CRC - CRC 值本身一方面,可能还有一些 header/trailer 不受 CRC 保护的字节(例如假设字节本身是常量,字节将对 CRC 值产生恒定影响。

尝试更改任何字节,或 adding/removing 一个字节 - 您将得到一个完全不同的值。

CRC 是一个常量,因为消息的最后 4 个字节是除消息的最后 4 个字节之外的所有字节的 CRC。 CRC 是一个非零常数,在本例中为 0x2144DF1C,因为 CRC 正在 post 补码(最终异或值 = 0xFFFFFFFF)。对于全零的 4 字节消息,您将获得相同的结果 (0x2144DF1C):

00 00 00 00

发生的事情是 4 个字节的零与初始值 0xFFFFFFFF 进行异或运算,然后计算 {FF FF FF FF} 的 CRC,得到 0xDEBB20E3,post 补码(最终异或值 = 0xFFFFFFFF) 得到 0x2144DF1C .

为了展示 CRC 最终 = 0 的情况,我补充了第一个和最后一个示例中的最后 4 个字节(消息 CRC)。如果您选择 CRC32,然后单击自定义,然后设置最终异或值 = 0,对于这两个示例,您将获得 CRC = 0:

aa aa 3 0 0 0 8 0 45 0 0 34 0 0 40 0 40 6 b7 e c0 a8 1 64 c0 a8 1 1 dd 95 0 50 f4 11 d8 cf 81 8e e5 e3 80 10 10 0 d6 4c 0 0 1 1 8 a f a7 bf e0 0 0 2a f9 25 4c 6e 42

aa aa 3 0 0 0 8 0 45 0 0 34 0 0 40 0 40 6 b7 e c0 a8 1 64 c0 a8 1 1 dd 8f 0 50 f ff 68 34 80 1c a4 f9 80 10 10 10 73 b8 0 0 1 1 8 a f a7 ba c 0 0 2a 62 1e D2 75 32