CRC32 チェックサムを逆にする方法を探しています。周りには解決策がありますが、それらはひどく書かれているか、非常に技術的であり、および/またはAssembly にあります。アセンブリは(現在)私の範囲を超えているので、誰かがより高いレベルの言語で実装をまとめてくれることを願っています。Ruby が理想ですが、PHP、Python、C、Java などを解析できます。
テイカーはいますか?
CRC32 チェックサムを逆にする方法を探しています。周りには解決策がありますが、それらはひどく書かれているか、非常に技術的であり、および/またはAssembly にあります。アセンブリは(現在)私の範囲を超えているので、誰かがより高いレベルの言語で実装をまとめてくれることを願っています。Ruby が理想ですが、PHP、Python、C、Java などを解析できます。
テイカーはいますか?
CRC32 は、元の文字列が 4 バイト以下の場合にのみ元に戻すことができます。
「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 のこのスレッドにコードを投稿しました。
私はそれに少し時間を費やしたので、より困難な問題に取り組んでいる人の助けになることを願っています: CRC32 の逆転 乾杯!