我正在寻找一种方法来反转CRC32 校验和。周围有一些解决方案,但它们要么写得不好,要么技术性很强,而且/或者在 Assembly 中。汇编(目前)超出了我的理解范围,所以我希望有人可以用更高级别的语言拼凑一个实现。Ruby 是理想的,但我可以解析 PHP、Python、C、Java 等。
有接盘侠吗?
我正在寻找一种方法来反转CRC32 校验和。周围有一些解决方案,但它们要么写得不好,要么技术性很强,而且/或者在 Assembly 中。汇编(目前)超出了我的理解范围,所以我希望有人可以用更高级别的语言拼凑一个实现。Ruby 是理想的,但我可以解析 PHP、Python、C、Java 等。
有接盘侠吗?
仅当原始字符串为 4 个字节或更少时,CRC32 才是可逆的。
阅读名为“Reversing CRC Theory and Practice”的文档。
这是 C#:
public class Crc32
{
public const uint poly = 0xedb88320;
public const uint startxor = 0xffffffff;
static uint[] table = null;
static uint[] revtable = null;
public void FixChecksum(byte[] bytes, int length, int fixpos, uint wantcrc)
{
if (fixpos + 4 > length) return;
uint crc = startxor;
for (int i = 0; i < fixpos; i++) {
crc = (crc >> 8) ^ table[(crc ^ bytes[i]) & 0xff];
}
Array.Copy(BitConverter.GetBytes(crc), 0, bytes, fixpos, 4);
crc = wantcrc ^ startxor;
for (int i = length - 1; i >= fixpos; i--) {
crc = (crc << 8) ^ revtable[crc >> (3 * 8)] ^ bytes[i];
}
Array.Copy(BitConverter.GetBytes(crc), 0, bytes, fixpos, 4);
}
public Crc32()
{
if (Crc32.table == null) {
uint[] table = new uint[256];
uint[] revtable = new uint[256];
uint fwd, rev;
for (int i = 0; i < table.Length; i++) {
fwd = (uint)i;
rev = (uint)(i) << (3 * 8);
for (int j = 8; j > 0; j--) {
if ((fwd & 1) == 1) {
fwd = (uint)((fwd >> 1) ^ poly);
} else {
fwd >>= 1;
}
if ((rev & 0x80000000) != 0) {
rev = ((rev ^ poly) << 1) | 1;
} else {
rev <<= 1;
}
}
table[i] = fwd;
revtable[i] = rev;
}
Crc32.table = table;
Crc32.revtable = revtable;
}
}
}
Cade Roux 关于逆转 CRC32 是正确的。
您提到的链接提供了一种解决方案,可以通过更改原始字节流来修复已失效的 CRC。此修复是通过更改一些(不重要的)字节来实现的,因此重新创建原始 CRC 值。
如果您知道创建它的多边形,则可以通过撤消位来生成原始 32 位来反转它。但是,如果您希望从给定文件中反转 CRC32 并在文件末尾附加一系列字节以匹配原始 CRC,我在 PHP 中的这个线程上发布了代码:
我花了一些时间在上面,所以我希望它可以帮助解决更棘手问题的人: Reversing CRC32 Cheers!