反转 CRC32

发布于 2025-01-05 19:48:40 字数 1921 浏览 0 评论 0 原文

我找到了一个反转 CRC32 的代码,但我不知道它是如何工作的,因为我不太擅长编程,我刚刚开始。我只想比较 2 个文件,即旧文件和新文件,然后在新文件中修复 CRC32 在文件末尾添加 4 个字节,因此这 2 个文件将具有相同的 CRC32。这是代码,用 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;
        }
    }
}

I found a code to reverse CRC32 but I don't know how it works, because im not that good in programming, I just started. I just want to compare 2 files, the old and the new one, then in the new fix the CRC32 adding 4 bytes at the end of the file, so the 2 files will have the same CRC32. Here is the code, is in 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;
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

掀纱窥君容 2025-01-12 19:48:40

这里有一些 PHP 代码,也可以满足您的需求
我花了很多时间试图出于合法目的这样做
所以我希望它能帮助某人

像这样的函数可以用于:

  1. 总是有一个哈希来验证文件(例如,某种类型的所有文件返回一个公共的crc,版本控制等。没有数据库)
  2. 修改哈希的方式分布式(例如分布式计算密钥平衡)
  3. 反转 crc32 的原始 4 个字节

要在线测试 crc32 字符串,您可以使用: http://www.lammertbies.nl/comm/info/crc-calculation.html

请参阅http://www.reversing.be/article.php?story=20061209172953555 摘自此处
由于我不是原作者,原作者在他的文章上花了很多时间,而且
提供了不小的帮助

这是 PHP 代码,可用于修改给定文件,如下所示:

<?php

//Calculate the original file's CRC32
$DesiredCRC32 = hexdec(hash_file('crc32b','originalcleanfile.ext'));

//Calculate the newfile's current CRC
$CurrentIncorrectCRC32 = hexdec(hash_file('crc32b','newupdatedfile.ext'));

//Generate a 4 byte string that, if appended to the newfile will result in the original CRC32
echo modCRC($DesiredCRC32,$CurrentIncorrectCRC32);  

// I should note that the original guy that posted this has some incorrect calcs on his page
// but if you read carefully and understand the math, you can pick up where it's incorrect
// and learn a thing or two (I beleive last time I tested this code it was accurate)

// if you wanted to do something via the CLI you could use something like: 
parse_str(implode('&', array_slice($argv, 1)), $_GET);
// and grab the files w/ 
$file1 =  $_GET['a'];
//... etc.

//then you could run it via something like this: 
//c:\php\php -f somefile.php a=c:\original.txt b=c:\new.txt c=c:\newwithcrc.txt




public static function modCRC($ExistingCRC, $DesiredCRC){

$crc32lookup = array(
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
);

//More Description:
//Want to append bytes: X  Y  Z  W 
//Take for register  a3 a2 a1 a0  (a is the 'already calculated' crc for string)
//Note that a3 is the most significant byte and a0 the least.
// f is the wanted new CRC byte string, and xyzw is the modification pad

/*
I'll show it a little different way:
a0 + X                  =(1)  points to  b3 b2 b1 b0  in table
a1 + b0 + Y             =(2)  points to  c3 c2 c1 c0  in table
a2 + b1 + c0 + Z        =(3)  points to  d3 d2 d1 d0  in table
a3 + b2 + c1 + d0 + W   =(4)  points to  e4 e3 e2 e1  in table
     b3 + c2 + d1 + e0  =f0
          c3 + d2 + e1  =f1
               d3 + e2  =f2
                    e3  =f3
    (1)  (2)  (3)  (4)
(figure 4)

This is reversed in the same way as the 16bit version. I shall give an example with real values. For the table values use the CRC-32 table in the appendix.
Take for CRC register before, a3 a2 a1 a0 -> AB CD EF 66
Take for CRC register after, f3 f2 f1 f0 -> 56 33 14 78 (wanted value)
Here we go:

First byte of entries            entry   value
e3=f3                     =56 -> 35h=(4) 56B3C423 for e3 e2 e1 e0
d3=f2+e2      =33+B3      =E6 -> 4Fh=(3) E6635C01 for d3 d2 d1 d0
c3=f1+e1+d2   =14+C4+63   =B3 -> F8h=(2) B3667A2E for c3 c2 c1 c0
b3=f0+e0+d1+c2=78+23+5C+66=61 -> DEh=(1) 616BFFD3 for b3 b2 b1 b0

Now we have all needed values, then
X=(1)+         a0=         DE+66=B8
Y=(2)+      b0+a1=      F8+D3+EF=C4
Z=(3)+   c0+b1+a2=   4F+2E+FF+CD=53
W=(4)+d0+c1+b2+a3=35+01+7A+6B+AB=8E
(final computation)
*/
  $ExistingCRC =  ~$ExistingCRC;
  $DesiredCRC = ~$DesiredCRC;

        //a3a2a1a0
        $a3 = (($ExistingCRC & 0xFF000000) >> 24) & 0x000000FF;
        $a2 = ($ExistingCRC & 0x00FF0000) >> 16;
        $a1 = ($ExistingCRC & 0x0000FF00) >> 8;
        $a0 = ($ExistingCRC & 0x000000FF);      

        //f3f2f1f0
        $f3 = (($DesiredCRC & 0xFF000000) >> 24) & 0x000000FF;
        $f2 = ($DesiredCRC & 0x00FF0000) >> 16;
        $f1 = ($DesiredCRC & 0x0000FF00) >> 8;
        $f0 = ($DesiredCRC & 0x000000FF);
        //echo "Existing CRC:" . dechex($ExistingCRC) . " DesiredCRC:" . dechex($DesiredCRC) . "<BR>";
        //echo "a3:" . dechex($a3) . " a2:" . dechex($a2) . " a1:" . dechex($a1) . " a0:" . dechex($a0) . "<br>";
        //echo "f3:" . dechex($f3) . " f2:" . dechex($f2) . " f1:" . dechex($f1) . " f0:" . dechex($f0) . "<br>";

        //capture e3/e2/e1/e0/(4) values
        for ($i = 0; $i < 256; $i++)
        {    
                if (($crc32lookup[$i] & 0xFF000000  ) == ($DesiredCRC & 0xFF000000)){
                $e3 = (($crc32lookup[$i] & 0xFF000000) >> 24) & 0x000000FF;
                $e2 = ($crc32lookup[$i] & 0x00FF0000) >> 16;
                $e1 = ($crc32lookup[$i] & 0x0000FF00) >> 8;
                $e0 = ($crc32lookup[$i] & 0x000000FF);
                $four = $i; 
                break;
                }
        }
        //echo "e3:" . dechex($e3) . " e2:" . dechex($e2) . " e1:" . dechex($e1) . " e0:" . dechex($e0) . "<br>";

        //$d3=f2+e2      =33+B3      =E6 -> 4Fh=(3) E6635C01 for d3 d2 d1 d0
        $d3 = $f2^$e2;    //lookup $d3 and assign the values for d2/d1/d0/(3)
        for ($i = 0; $i < 256; $i++)
        {       
                if (($crc32lookup[$i] & 0xFF000000  ) == ($d3 << 24)){
                $d2 = ($crc32lookup[$i] & 0x00FF0000) >> 16;
                $d1 = ($crc32lookup[$i] & 0x0000FF00) >> 8;
                $d0 = ($crc32lookup[$i] & 0x000000FF);
                $three = $i; 
                break;
                }
        }
        //echo "d3:" . dechex($d3) . " d2:" . dechex($d2) . " d1:" . dechex($d1) . " d0:" . dechex($d0) . "<br>";
        //c3=f1+e1+d2   =14+C4+63   =B3 -> F8h=(2) B3667A2E for c3 c2 c1 c0
        $c3 = $f1^$e1^$d2;

        for ($i = 0; $i < 256; $i++)
        {   
                if (($crc32lookup[$i] & 0xFF000000  ) == ($c3 << 24)){
                $c2 = ($crc32lookup[$i] & 0x00FF0000) >> 16;
                $c1 = ($crc32lookup[$i] & 0x0000FF00) >> 8;
                $c0 = ($crc32lookup[$i] & 0x000000FF);
                $two = $i; 
                break;
                }
        }
        //echo "c3:" . dechex($c3) . " c2:" . dechex($c2) . " c1:" . dechex($c1) . " c0:" . dechex($c0) . "<br>";
        //b3=f0+e0+d1+c2=78+23+5C+66=61 -> DEh=(1) 616BFFD3 for b3 b2 b1 b0
        $b3 = $f0^$e0^$d1^$c2;
        for  ($i = 0; $i < 256; $i++)
        {   
                if (($crc32lookup[$i] & 0xFF000000  ) == ($b3 << 24)){
                $b2 = ($crc32lookup[$i] & 0x00FF0000) >> 16;
                $b1 = ($crc32lookup[$i] & 0x0000FF00) >> 8;
                $b0 = ($crc32lookup[$i] & 0x000000FF);
                $one = $i;
                break;
                }
        }
        /*
        Now we have all needed values, then
        X=(1)+         a0=         DE+66=B8
        Y=(2)+      b0+a1=      F8+D3+EF=C4
        Z=(3)+   c0+b1+a2=   4F+2E+FF+CD=53
        W=(4)+d0+c1+b2+a3=35+01+7A+6B+AB=8E
        (final computation)
        */
        $X = $one ^ $a0;
        $Y = $two ^ $b0^$a1;
        $Z = $three ^ $c0^$b1^$a2;
        $W = $four ^ $d0 ^ $c1 ^ $b2^$a3;

    //echo "Four:" . dechex($four) . " Three:" .dechex($three)." Two:".dechex($two)."One:" .dechex($one) . "<br>";
    //echo "X:" . dechex($X) . " Y:" . dechex($Y) . " Z:" . dechex($Z) . " W:" . dechex($W) . "<br>";
    return chr($X) .  chr($Y) . chr($Z) . chr($W);
}
?>

Here's some PHP code that will also do what you're looking for
I spent a great deal of time trying to do this for legitimate purposes
so I hope it helps someone

Functions like this could be used to:

  1. always have a single hash that verifies files (e.g. all files of a certain type return a common crc, versioning etc. w/o having a database)
  2. modify the way hashes are distributed (e.g. distributed computing key balancing)
  3. reverse original 4 bytes of a crc32

To test crc32 strings online you can use: http://www.lammertbies.nl/comm/info/crc-calculation.html

See http://www.reversing.be/article.php?story=20061209172953555 from where this was adapted from
as I'm not the original author, the original spent a great deal of time on his essay, and it
helped in no small way

Here's PHP code which can be used to modify a given file as follows:

<?php

//Calculate the original file's CRC32
$DesiredCRC32 = hexdec(hash_file('crc32b','originalcleanfile.ext'));

//Calculate the newfile's current CRC
$CurrentIncorrectCRC32 = hexdec(hash_file('crc32b','newupdatedfile.ext'));

//Generate a 4 byte string that, if appended to the newfile will result in the original CRC32
echo modCRC($DesiredCRC32,$CurrentIncorrectCRC32);  

// I should note that the original guy that posted this has some incorrect calcs on his page
// but if you read carefully and understand the math, you can pick up where it's incorrect
// and learn a thing or two (I beleive last time I tested this code it was accurate)

// if you wanted to do something via the CLI you could use something like: 
parse_str(implode('&', array_slice($argv, 1)), $_GET);
// and grab the files w/ 
$file1 =  $_GET['a'];
//... etc.

//then you could run it via something like this: 
//c:\php\php -f somefile.php a=c:\original.txt b=c:\new.txt c=c:\newwithcrc.txt




public static function modCRC($ExistingCRC, $DesiredCRC){

$crc32lookup = array(
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
);

//More Description:
//Want to append bytes: X  Y  Z  W 
//Take for register  a3 a2 a1 a0  (a is the 'already calculated' crc for string)
//Note that a3 is the most significant byte and a0 the least.
// f is the wanted new CRC byte string, and xyzw is the modification pad

/*
I'll show it a little different way:
a0 + X                  =(1)  points to  b3 b2 b1 b0  in table
a1 + b0 + Y             =(2)  points to  c3 c2 c1 c0  in table
a2 + b1 + c0 + Z        =(3)  points to  d3 d2 d1 d0  in table
a3 + b2 + c1 + d0 + W   =(4)  points to  e4 e3 e2 e1  in table
     b3 + c2 + d1 + e0  =f0
          c3 + d2 + e1  =f1
               d3 + e2  =f2
                    e3  =f3
    (1)  (2)  (3)  (4)
(figure 4)

This is reversed in the same way as the 16bit version. I shall give an example with real values. For the table values use the CRC-32 table in the appendix.
Take for CRC register before, a3 a2 a1 a0 -> AB CD EF 66
Take for CRC register after, f3 f2 f1 f0 -> 56 33 14 78 (wanted value)
Here we go:

First byte of entries            entry   value
e3=f3                     =56 -> 35h=(4) 56B3C423 for e3 e2 e1 e0
d3=f2+e2      =33+B3      =E6 -> 4Fh=(3) E6635C01 for d3 d2 d1 d0
c3=f1+e1+d2   =14+C4+63   =B3 -> F8h=(2) B3667A2E for c3 c2 c1 c0
b3=f0+e0+d1+c2=78+23+5C+66=61 -> DEh=(1) 616BFFD3 for b3 b2 b1 b0

Now we have all needed values, then
X=(1)+         a0=         DE+66=B8
Y=(2)+      b0+a1=      F8+D3+EF=C4
Z=(3)+   c0+b1+a2=   4F+2E+FF+CD=53
W=(4)+d0+c1+b2+a3=35+01+7A+6B+AB=8E
(final computation)
*/
  $ExistingCRC =  ~$ExistingCRC;
  $DesiredCRC = ~$DesiredCRC;

        //a3a2a1a0
        $a3 = (($ExistingCRC & 0xFF000000) >> 24) & 0x000000FF;
        $a2 = ($ExistingCRC & 0x00FF0000) >> 16;
        $a1 = ($ExistingCRC & 0x0000FF00) >> 8;
        $a0 = ($ExistingCRC & 0x000000FF);      

        //f3f2f1f0
        $f3 = (($DesiredCRC & 0xFF000000) >> 24) & 0x000000FF;
        $f2 = ($DesiredCRC & 0x00FF0000) >> 16;
        $f1 = ($DesiredCRC & 0x0000FF00) >> 8;
        $f0 = ($DesiredCRC & 0x000000FF);
        //echo "Existing CRC:" . dechex($ExistingCRC) . " DesiredCRC:" . dechex($DesiredCRC) . "<BR>";
        //echo "a3:" . dechex($a3) . " a2:" . dechex($a2) . " a1:" . dechex($a1) . " a0:" . dechex($a0) . "<br>";
        //echo "f3:" . dechex($f3) . " f2:" . dechex($f2) . " f1:" . dechex($f1) . " f0:" . dechex($f0) . "<br>";

        //capture e3/e2/e1/e0/(4) values
        for ($i = 0; $i < 256; $i++)
        {    
                if (($crc32lookup[$i] & 0xFF000000  ) == ($DesiredCRC & 0xFF000000)){
                $e3 = (($crc32lookup[$i] & 0xFF000000) >> 24) & 0x000000FF;
                $e2 = ($crc32lookup[$i] & 0x00FF0000) >> 16;
                $e1 = ($crc32lookup[$i] & 0x0000FF00) >> 8;
                $e0 = ($crc32lookup[$i] & 0x000000FF);
                $four = $i; 
                break;
                }
        }
        //echo "e3:" . dechex($e3) . " e2:" . dechex($e2) . " e1:" . dechex($e1) . " e0:" . dechex($e0) . "<br>";

        //$d3=f2+e2      =33+B3      =E6 -> 4Fh=(3) E6635C01 for d3 d2 d1 d0
        $d3 = $f2^$e2;    //lookup $d3 and assign the values for d2/d1/d0/(3)
        for ($i = 0; $i < 256; $i++)
        {       
                if (($crc32lookup[$i] & 0xFF000000  ) == ($d3 << 24)){
                $d2 = ($crc32lookup[$i] & 0x00FF0000) >> 16;
                $d1 = ($crc32lookup[$i] & 0x0000FF00) >> 8;
                $d0 = ($crc32lookup[$i] & 0x000000FF);
                $three = $i; 
                break;
                }
        }
        //echo "d3:" . dechex($d3) . " d2:" . dechex($d2) . " d1:" . dechex($d1) . " d0:" . dechex($d0) . "<br>";
        //c3=f1+e1+d2   =14+C4+63   =B3 -> F8h=(2) B3667A2E for c3 c2 c1 c0
        $c3 = $f1^$e1^$d2;

        for ($i = 0; $i < 256; $i++)
        {   
                if (($crc32lookup[$i] & 0xFF000000  ) == ($c3 << 24)){
                $c2 = ($crc32lookup[$i] & 0x00FF0000) >> 16;
                $c1 = ($crc32lookup[$i] & 0x0000FF00) >> 8;
                $c0 = ($crc32lookup[$i] & 0x000000FF);
                $two = $i; 
                break;
                }
        }
        //echo "c3:" . dechex($c3) . " c2:" . dechex($c2) . " c1:" . dechex($c1) . " c0:" . dechex($c0) . "<br>";
        //b3=f0+e0+d1+c2=78+23+5C+66=61 -> DEh=(1) 616BFFD3 for b3 b2 b1 b0
        $b3 = $f0^$e0^$d1^$c2;
        for  ($i = 0; $i < 256; $i++)
        {   
                if (($crc32lookup[$i] & 0xFF000000  ) == ($b3 << 24)){
                $b2 = ($crc32lookup[$i] & 0x00FF0000) >> 16;
                $b1 = ($crc32lookup[$i] & 0x0000FF00) >> 8;
                $b0 = ($crc32lookup[$i] & 0x000000FF);
                $one = $i;
                break;
                }
        }
        /*
        Now we have all needed values, then
        X=(1)+         a0=         DE+66=B8
        Y=(2)+      b0+a1=      F8+D3+EF=C4
        Z=(3)+   c0+b1+a2=   4F+2E+FF+CD=53
        W=(4)+d0+c1+b2+a3=35+01+7A+6B+AB=8E
        (final computation)
        */
        $X = $one ^ $a0;
        $Y = $two ^ $b0^$a1;
        $Z = $three ^ $c0^$b1^$a2;
        $W = $four ^ $d0 ^ $c1 ^ $b2^$a3;

    //echo "Four:" . dechex($four) . " Three:" .dechex($three)." Two:".dechex($two)."One:" .dechex($one) . "<br>";
    //echo "X:" . dechex($X) . " Y:" . dechex($Y) . " Z:" . dechex($Z) . " W:" . dechex($W) . "<br>";
    return chr($X) .  chr($Y) . chr($Z) . chr($W);
}
?>
攀登最高峰 2025-01-12 19:48:40

您想知道它是如何工作的,或者如何使用它吗?

如果是后者,则从代码签名来看:

public void FixChecksum(byte[] bytes, int length, int fixpos, uint wantcrc)

似乎您将第二个文件的内容放入一个数组中(末尾有额外的 4 个字节用于修复),并将其作为 bytes 参数。您将此数组的长度作为 length 参数传递,将偏移量传递到要插入修复的位置(在本例中为 length - 4)作为 fixpos 参数,并将您想要的CRC作为wantcrc参数,您可以通过计算第一个文件的CRC来获得该值。

FixChecksum 方法似乎将 4 字节修复写入您提供的数组中您提供的偏移量处。调用 FixChecksum 后,您只需将结果写入第二个文件。

Would you like to know how it works, or how to use it?

If it's the later, than from the code signature:

public void FixChecksum(byte[] bytes, int length, int fixpos, uint wantcrc)

It seems that you put the contents of your second file to an array (with additional 4 bytes at the end for the fix), and pass it as the bytes parameter. You pass the lengths of this array as the length parameter, you pass the offset to the place to insert the fix to, (in this case length - 4) as fixpos parameter, and you put your desired CRC as wantcrc parameter, you can obtain this value, by calculating CRC of the first file.

FixChecksum method appears to write the 4 bytes fix in the array you have provided at the offset you have provided. After you've made the call to FixChecksum you just need to write the results to your second file.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文