我在程序中需要验证png各段的CRC,后来从网上搜得该段代码,可不知为什么,我输入数据得出的结果总与实际结果不符,现贴出该段代码,请高手指点!十分感谢!!!以下是C++Builder代码,与Delphi类似!!!//---------------------------------------------------------------------------
// 构造 32 位 CRC 表
void TForm1::BuildTable32( unsigned long aPoly )
{
 unsigned long i, j;
 unsigned long nData;
 unsigned long nAccum; String str; //Memo1->Clear(); for ( i = 0; i < 256; i++ )
 {
        nData = ( unsigned long )( i << 24 );
        nAccum = 0;
        for ( j = 0; j < 8; j++ )
        {
                if ( ( nData ^ nAccum ) & 0x80000000 )
                        nAccum = ( nAccum << 1 ) ^ aPoly;
                else
                        nAccum <<= 1;
                nData <<= 1;
        }
        Table_CRC[i] = nAccum;        str = IntToStr(i)+", "+(nAccum);
        //Memo1->Lines->Add(str);
 }
}//---------------------------------------------------------------------------
// 计算 32 位 CRC-32 值
unsigned long TForm1::CRC_32( unsigned char * aData, unsigned long aSize )
{
 unsigned long i;
 unsigned long nAccum = 0; for ( i = 0; i < aSize; i++ )
        nAccum = ( nAccum << 8 ) ^ Table_CRC[( nAccum >> 24 ) ^ (*aData++)]; return nAccum;
}//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
 unsigned long crc;
 String str; byte testcrc[8]={
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
(byte)0x49, (byte)0x45, (byte)0x4E, (byte)0x44,
}; //这是png文件IEND部分固定的数据 
 //这是该段固定的CRC = (byte)0xAE, (byte)0x42, (byte)0x60, (byte)0x82
 //而我用该方法计算出的CRC=91, A5, D1, 8C请问我错在哪里?应该怎么改?
 /*
 //列出另一IDAT数据块
 byte testcrc[47]={
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x27,
  (byte)0x49, (byte)0x44, (byte)0x41, (byte)0x54,
  (byte)0x78, (byte)0x9c, (byte)0x63, (byte)0x38,
  (byte)0xbd, (byte)0xb2, (byte)0x3d, (byte)0x95,
  (byte)0x61, (byte)0xd7, (byte)0x8c, (byte)0xb2,
  (byte)0x10, (byte)0x06, (byte)0x20, (byte)0xc3,
  (byte)0x99, (byte)0x01, (byte)0xc8, (byte)0x30,
  (byte)0x62, (byte)0x00, (byte)0x32, (byte)0x14,
  (byte)0x19, (byte)0x80, (byte)0x0c, (byte)0x01,
  (byte)0x06, (byte)0x10, (byte)0x83, (byte)0x01,
  (byte)0xc4, (byte)0x00, (byte)0x00, (byte)0x24,
  (byte)0xa7, (byte)0x0b, (byte)0xa4
  };
 //最后的CRC应该是DA 12 06 A5
 //该方法计算得89 AC 1D 7C
 */
 unsigned long cnCRC_32 = 0x04C10DB7; BuildTable32(cnCRC_32); crc = CRC_32( testcrc, 8); str = "crc="+IntToHex((int)crc,4);
 str += ", a1="+ IntToHex((int)(crc>>24), 2);
 str += ", a2="+ IntToHex((int)((crc>>16)&0xFF), 2);
 str += ", a3="+ IntToHex((int)((crc>>8)&0xFF), 2);
 str += ", a4="+ IntToHex((int)((crc)&0xFF), 2);
 Label1->Caption = str;
}
//---------------------------------------------------------------------------

解决方案 »

  1.   

    朋友们帮帮忙吧,将CRC的初植写成0xFFFFFFFF还是不对。
      

  2.   

    兄弟们,你们试试你们的代码看结果是不是png文件中那几个固定的值?
      

  3.   

    .h 文件
    // http://www.w3.org/TR/PNG/#D-CRCAppendix
    class CPngCyclicRedundancyCode 
    {
    private:
    static unsigned long crc_table[256]; /* Make the table for a fast CRC. */
    static int make_crc_table(void)
    {
    unsigned long c; for (int n = 0; n < 256; n++)
    {
    c = (unsigned long) n;
    for (int k = 0; k < 8; k++)
    {
    if (c & 1)
    c = 0xedb88320L ^ (c >> 1);
    else
    c = c >> 1;
    }
    crc_table[n] = c;
    } return 0;
    } /* Update a running CRC with the bytes buf[0..len-1]--the CRC
          should be initialized to all 1's, and the transmitted value
          is the 1's complement of the final running CRC (see the
          crc() routine below). */
    static unsigned long update_crc(unsigned long crc, unsigned char *buf, int len)
    {
    static int ntemp = make_crc_table(); unsigned long c = crc;
    for (int n = 0; n < len; n++)
    c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); return c;
    }public:
    /* Return the CRC of the bytes buf[0..len-1]. */
    static unsigned long crc(unsigned char *buf, int len)
    {
    return update_crc(0xffffffffL, buf, len) ^ 0xffffffffL;
    }
    };.cpp 文件
    unsigned long CPngCyclicRedundancyCode::crc_table[256];测试代码:
    注意png chunk 的长度字段不列入计算:
    unsigned char iend[8] = { 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44 };
    unsigned long lcrc = CPngCyclicRedundancyCode::crc(iend + 4, 4);
    cout << "crc = " << hex << lcrc << endl;
    return 0;参考:
    http://blog.csdn.net/egxsguo/archive/2006/10/23/1346315.aspx
    http://www.w3.org/TR/PNG/#D-CRCAppendix