algorithm - 如何在保持 CRC-32 校验和的同时修改文件?

标签 algorithm crc crc32

我正在尝试修改的一款旧游戏具有 CRC-32 校验。我无权访问 CRC 校验和本身,因此我必须修改文件,同时保持相同的校验和输出。

我的信息

  • 文件,如果文件本身是CRC-32程序的唯一输入,我可以计算出CRC-32校验和应该是多少。

  • 32 位多项式代码。

最佳答案

正如@MrSmith42 所说,只要您不需要保持文件长度不变,就可以轻松计算出“冲突”(为产生相同散列的两个输入消息指定的名称)。

它很繁琐,有很多小 Action ,但速度非常快。

假设原始文件是,十六进制:

1122334455667788

然后它的 CRC-32 校验和将是 0x9118E1C2 使用标准 CRC32 多项式。如果使用的算法不标准,可以替换。出于演示目的,我将坚持使用标准。

首先,根据需要更改文件。例如,我改变了中间的一个字节:

11223344FF667788

恢复 CRC 的第一步是用 4 个零字节填充文件:

11223344FF66778800000000

CRC 校验和现在是 0x6BBE83C9

第二步,异或两个校验和:

0x9118E1C2 XOR 0x6BBE83C9 = 0xFAA6620B

第三步,对结果进行位反转:

Bit reverse of 0xFAA6620B = 0xD046655F

第四步,这有点古怪,所以请看下面,执行反向 CRC32 计算:

0xD046655F * inverse(x32) mod crc_poly = 0xe4c7d232

第五步,对结果进行位反转,这次是按字节:

0xe4c7d232 bit reversed byte-wise = 0x27E34B4C

第六步,用结果替换填充的字节

11223344FF66778827E34B4C

瞧,CRC32 校验和值现在回到 0x9118E1C2。

据我所知,执行反向 CRC 计算的最简单方法是使用 Python 中的 BitVector 包:

>>> import BitVector as bv
>>> poly = bv.BitVector(intVal = 0x104C11DB7) # "standard" CRC32 polynomial
>>> inv = bv.BitVector(intVal = 0x100000000).gf_MI(poly, 32)
>>> k = 0xD046655F
>>> p = bv.BitVector(intVal = k).gf_multiply_modular(inv, poly, 32)
>>> print(p.getHexStringFromBitVector())
e4c7d232

此算法由 Redditor/u/supersaw7 发表于 this thread .我还没有遇到更好的版本,尽管可能有更简单的版本。

关于algorithm - 如何在保持 CRC-32 校验和的同时修改文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48247647/

相关文章:

java - 将 C 中的 crc8 函数转换为 Java

python - 难以比较生成的和谷歌云存储提供的 CRC32c 校验和

vhdl - 串行 ATA (SATA) 的 CRC 计算

algorithm - 地形四叉树 LOD 裂缝/T 型连接

python - Python 中的 CRC16

algorithm - sklearn k最近邻居问题

crc - 了解使用 LFSR 实现 CRC 生成的两种不同方法

python - 使用缓冲区在 Python 中的二进制文件上计算 CRC/CRC32 哈希/校验和

algorithm - O( polylog(n) ) 是什么意思?特别是,polylog(n) 是如何定义的?

c++ - 在 C/C++ 中实现导数