指定CRC32反构数据

指定CRC反构数据

【摘要】
针对CRC32算法,给定希望产生的CRC32校验和,通过修改给定文件中连续4个字节,将CRC32改变成希望产生的值。

1、 题目

  给出一组具体的题目,可以便于对问题的分析与解答,并用来验证算法的正确。
  已知如下数据:
00 01 02 03 04 05 06 07 08 09 ?? ?? ?? ?? 0A 0B 0C 0D 0E 0F
  向问号处填入4个字节的数字,使数据的CRC32校验和为DEADBEEF

2、 CRC32算法

  这里的CRC32校验和,以主流文件校验工具提供的CRC32为准,其模型为:
Bits=32,(校验和的位数)
TruncPoly=0x104C11DB7,(多项式系数序列)
InitRem=0xFFFFFFFF,(余数的初值)
FinalXor=0xFFFFFFFF,(最终结果需要异或的值)
ReflectIn=true,(数据输入时高低颠倒)
ReflectRem=true。(余数输出之前先高低颠倒)
  其中,TruncPoly最高位的1通常省略不写,也就是0x04C11DB7
  下面给出一个典型的计算函数。函数中,CRC32算法的核心部分,在于前半部分的移位,按情况与多项式的异或。至于后边将余数的高低位进行的颠倒,以及最终异或的常量,只是收尾。
  计算函数如下:

#include <assert.h>
#include <stdint.h>

uint32_t crc32_checksum( const uint8_t *buf, unsigned len )
{
    assert (buf != 0);

    // initial remainder
    uint32_t rem = 0xFFFFFFFF;
    for (unsigned i = 0; i < len; ++i)
    {
        // reflect input
        for (unsigned j = 31; j >= 24; --j)
        {
            if (((buf[i] << j) ^ rem) & 0x80000000)
            {
                // truncated polynominal
                rem = (rem << 1) ^ 0x04C11DB7;
            }
            else
            {
                rem = rem << 1;
            }
        }
    }

    // reflect remainder
    uint32_t ref = 0;
    for (unsigned i = 0; i < 32; ++i)
    {
        ref |= ((rem >> i) & 1) << (31 - i);
    }

    // final xor value
    return ref ^ 0xFFFFFFFF;
}

3、 定义运算符

  定义需要的运算符,可以便于书写、推导计算方法。
  仿照CRC32算法核心部分,定义二进制序列的“冗余”运算符:“\”,二进制序列X对多项式P(保留最高位的1,共计33位)的冗余:X\P,其定义为:
  直到X的高于32的位全部为0为止,找到X的不为0的最高位的位置n,将P左移(32-n)位得到Q,通过把X^Q赋值给X,使X的不为0的最高位成为0,不断重复该过程;最后保留X的最低32位,就是冗余的结果。上述操作只是为了得到运算结果,而不是修改X的值。
  定义了冗余运算符,就可以写出循环冗余的核心部分的递推公式:

Rn+1=((Rn<<1)^(In<<32))P,n=0,1,2,3,...

  设 Rn=Rn^(In<<31) Rn 的最高位即第31位记做 r31 ,也就是:
Rn+1={ Rn<<1,(Rn<<1)^P,r31=0r31=1

  其中, << <script type="math/tex" id="MathJax-Element-6"><<</script>是左移操作的运算符, ^ 是异或操作的运算符, Rn 是记录余数的寄存器(共计32位), R0 是寄存器的初值, In 是输入数据的第 n 个位, P 是除数多项式(共计33位)。
  由于我们习惯按照字节进行处理,所以再列出针对字节流 In+7In+6In 的递推公式:
Rn+8=((Rn<<8)^(InIn+1In+7<<32))P,n=0,1,2,3,

  其中,输入数据的字节顺序进行了高低颠倒,原因在于参数 ReflectIn为真。注意,参数 ReflectIn的含义为,字节内的位是否颠倒输入。为假表示不需要颠倒,按照从高位到低位的顺序依次输入;为真表示需要颠倒,按照从低位到高位的顺序依次输入。另外, n 的取值不仅仅是0、8、16、24……当 n 为1、2、3、……时,上述递推公式仍然是成立的,所以 n 的有效范围仍然写作0、1、2、3……

4、 逆运算和反运算

  循环冗余的递推公式是可逆的。在循环冗余递推公式中, P 是固定的常量,已知 Rn In ,可以求得 Rn+1

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值