delphi2007 教程

delphi2007 教程

首页 新随笔 联系 聚合 管理
  1013 Posts :: 0 Stories :: 28 Comments :: 0 Trackbacks
CRC32算法问题 Delphi / Windows SDK/API
http://www.delphi2007.net/DelphiBase/html/delphi_20061206182220256.html
#include   "stdafx.h"  
  #include   "crc.h"  
   
   
  DWORD   CCrc::CrcTable[256];  
  BOOL     CCrc::m_bInitCrc   =   FALSE;  
   
  //-----------------------------------------------------------------------------  
  //   generate   the   table   of   CRC   remainders   for   all   possible   bytes  
  //-----------------------------------------------------------------------------  
  VOID   CCrc::InitCrcTable()  
  {  
  static   bool   bInited   =   false;  
   
  if   (bInited) //   确保只初始化一次  
  return;  
   
  register   int   i,   j;  
  register   unsigned   long   crc_accum;  
  for   (   i   =   0;     i   <   256;     i++   )  
  {    
  crc_accum   =   (   (unsigned   long)   i   <<   24   );  
  for   (   j   =   0;     j   <   8;     j++   )  
  {  
  if(   crc_accum   &   0x80000000L   )    
  crc_accum   =   (   crc_accum   <<   1   )   ^   POLYNOMIAL;  
  else    
  crc_accum   =   (   crc_accum   <<   1   );    
  }  
  CrcTable[i]   =   crc_accum;    
  }  
   
  bInited   =   true;  
  }  
   
   
   
   
  //-----------------------------------------------------------------------------  
  //   calculate   32   crc  
  //-----------------------------------------------------------------------------  
  DWORD   CCrc::Crc(LPCTSTR   lpData)  
  {  
  if(   FALSE   ==   m_bInitCrc   )  
  {  
  InitCrcTable();  
  m_bInitCrc   =   TRUE;  
  }  
  unsigned   int   result;  
   
  //对超过127的字符,   必须用unsigned   char,   否则会出错  
  const   unsigned   char   *data   =   (const   unsigned   char   *)lpData;  
  if(   data[0]   ==   0   )   return   0;  
   
  result     =   *data++   <<   24;  
  if(   *data   )  
  {  
  result   |=   *data++   <<   16;  
  if(   *data   )  
  {  
  result   |=   *data++   <<   8;  
  if(   *data   )   result   |=   *data++;  
  }  
  }  
  result   =   ~   result;  
   
  while(   *data   )  
  {  
  result   =   (result   <<   8   |   *data)   ^   CrcTable[result   >>   24];  
  data++;  
  }  
   
  return   ~result;  
  }  
  ---------------------------  
  这是C++版的CRC32的算法,各位大哥帮忙翻译成DELPHI版的算法,小弟感激不尽

(*//  
  标题:CRC验证单元  
  说明:CRC16和CRC32  
  日期:2005-01-16  
  设计:Zswang  
  支持:wjhu111#21cn.com  
  //*)  
   
  unit   CRCUtils;  
   
  interface  
   
  uses   Windows,   Classes,   SysUtils;  
   
  function   UpdateCRC16(   //更新CRC16的值  
      mChar:   Char;   //字符  
      mSeed:   Word   //Seed  
  ):   Word;   //返回更新后的CRC16值  
   
  function   UpdateCRC32(   //更新CRC32的值  
      mChar:   Char;   //字符  
      mSeed:   DWORD   //Seed  
  ):   DWORD;   //返回更新后的CRC32值  
   
  function   StringCRC16(   //取得字符串的CRC16值  
      mString:   string   //字符串  
  ):   Word;   //返回字符串的CRC16值  
   
  function   StringCRC32(   //取得字符串的CRC32值  
      mString:   string   //字符串  
  ):   DWORD;//返回字符串的CRC32值  
   
  function   FileCRC16(   //取得文件的CRC16值  
      mFileName:   TFileName   //文件名  
  ):   Word;   //返回文件的CRC16值  
   
  function   FileCRC32(   //取得文件的CRC32值  
      mFileName:   TFileName   //文件名  
  ):   DWORD;   //返回文件的CRC32值  
   
  implementation  
   
  const  
      cBufferSize   =   $1000;   //预处理的缓冲大小  
   
  var  
      vCRC16Table:   array[Byte]   of   Word;   //CRC16表  
      vCRC32Table:   array[Byte]   of   DWORD;   //CRC32表  
   
  procedure   MakeCRC16Table;   //生存CRC16表  
  var  
      vCRC:   Word;  
      I,   J:   Byte;  
  begin  
      for   I   :=   0   to   255   do  
      begin  
          vCRC   :=   I;  
          for   J   :=   1   to   8   do  
              if   Odd(vCRC)   then  
                  vCRC   :=   (vCRC   shr   1)   xor   $8408  
              else   vCRC   :=   vCRC   shr   1;  
          vCRC16Table[I]   :=   vCRC;  
      end;  
  end;   {   MakeCRC16Table   }  
   
  procedure   MakeCRC32Table;   //生存CRC32表  
  var  
      vCRC:   DWORD;  
      I,   J:   Byte;  
  begin  
      for   I   :=   0   to   255   do  
      begin  
          vCRC   :=   I;  
          for   J   :=   1   to   8   do  
              if   Odd(vCRC)   then  
                  vCRC   :=   (vCRC   shr   1)   xor   $EDB88320  
              else   vCRC   :=   vCRC   shr   1;  
          vCRC32Table[I]   :=   vCRC;  
      end;  
  end;   {   MakeCRC32Table   }  
   
  function   UpdateCRC16(   //更新CRC16的值  
      mChar:   Char;   //字符  
      mSeed:   Word   //Seed  
  ):   Word;   //返回更新后的CRC16值  
  begin  
      Result   :=  
          vCRC16Table[(mSeed   and   $000000FF)   xor   Byte(mChar)]   xor   (mSeed   shr   8);  
  end;   {   UpdateCRC16   }  
   
  function   UpdateCRC32(   //更新CRC32的值  
      mChar:   Char;   //字符  
      mSeed:   DWORD   //Seed  
  ):   DWORD;   //返回更新后的CRC32值  
  begin  
      Result   :=  
          vCRC32Table[(mSeed   and   $000000FF)   xor   Byte(mChar)]   xor   (mSeed   shr   8);  
  end;   {   UpdateCRC32   }  
   
  function   StringCRC16(   //取得字符串的CRC16值  
      mString:   string   //字符串  
  ):   Word;   //返回字符串的CRC16值  
  var  
      I:   Integer;  
  begin  
      Result   :=   $FFFF;  
      for   I   :=   1   to   Length(mString)   do   Result   :=   UpdateCRC16(mString[I],   Result);  
      Result   :=   not   Result;  
  end;   {   StringCRC16   }  
   
  function   StringCRC32(   //取得字符串的CRC32值  
      mString:   string   //字符串  
  ):   DWORD;//返回字符串的CRC32值  
  var  
      I:   Integer;  
  begin  
      Result   :=   $FFFFFFFF;  
      for   I   :=   1   to   Length(mString)   do   Result   :=   UpdateCRC32(mString[I],   Result);  
      Result   :=   not   Result;  
  end;   {   StringCRC32   }  
   
  function   FileCRC16(   //取得文件的CRC16值  
      mFileName:   TFileName   //文件名  
  ):   Word;   //返回文件的CRC16值  
  var  
      vBuffer:   array[0..cBufferSize   -   1]   of   Char;  
      I,   J:   Integer;  
  begin  
      Result   :=   $FFFF;  
      if   not   FileExists(mFileName)   then   Exit;  
      with   TFileStream.Create(mFileName,   fmOpenRead)   do   try  
          I   :=   Read(vBuffer[0],   SizeOf(vBuffer));  
          while   I   >   0   do  
          begin  
              for   J   :=   0   to   I   -   1   do   Result   :=   UpdateCRC16(vBuffer[J],   Result);  
              I   :=   Read(vBuffer[0],   SizeOf(vBuffer));  
          end;  
          Result   :=   not   Result;  
      finally  
          Free;  
      end;  
  end;   {   FileCRC16   }  
   
  function   FileCRC32(   //取得文件的CRC32值  
      mFileName:   TFileName   //文件名  
  ):   DWORD;   //返回文件的CRC32值  
  var  
      vBuffer:   array[0..cBufferSize   -   1]   of   Char;  
      I,   J:   Integer;  
  begin  
      Result   :=   $FFFFFFFF;  
      if   not   FileExists(mFileName)   then   Exit;  
      with   TFileStream.Create(mFileName,   fmOpenRead)   do   try  
          I   :=   Read(vBuffer[0],   SizeOf(vBuffer));  
          while   I   >   0   do  
          begin  
              for   J   :=   0   to   I   -   1   do   Result   :=   UpdateCRC32(vBuffer[J],   Result);  
              I   :=   Read(vBuffer[0],   SizeOf(vBuffer));  
          end;  
          Result   :=   not   Result;  
      finally  
          Free;  
      end;  
  end;   {   FileCRC32   }  
   
  initialization  
      MakeCRC16Table;  
      MakeCRC32Table;  
   
  finalization  
   
  end.  
   
 

大哥你给出的算法跟我这个C++版的算法算出来的值还是不一样啊!

//照着写一个,测试通过  
   
  unit   Unit2;  
   
  interface  
   
  uses   Windows;  
   
  function   Crc(lpData:   LPCTSTR):   DWORD;  
   
  implementation  
   
  const  
      POLYNOMIAL   =   $EDB88320;   //   注意这个值是否定义一样  
   
  var  
      CrcTable:   array[0..256   -   1]   of   DWORD;  
      m_bInitCrc:   Boolean   =   False;  
   
  procedure   InitCrcTable;  
  {$J+}   //   静态变量  
  const  
      bInited:   Boolean   =   False;  
  {$J-}  
  var  
      I,   J:   Integer;  
      crc_accum:   Longword;  
  begin  
      if   bInited   then   Exit;   //   确保只初始化一次  
      for   I   :=   0   to   256   -   1   do  
      begin  
          crc_accum   :=   I   shl   24;  
          for   J   :=   0   to   8   -   1   do  
          begin  
              if   (crc_accum   and   $80000000)   <>   0   then  
                  crc_accum   :=   (crc_accum   shl   1)   xor   POLYNOMIAL  
              else   crc_accum   :=   crc_accum   shl   1;  
          end;  
          CrcTable[I]   :=   crc_accum;  
      end;  
      bInited   :=   True;  
  end;  
   
  function   Crc(lpData:   LPCTSTR):   DWORD;  
  var  
      Data:   PByte;  
  begin  
      Result   :=   0;  
      if   not   m_bInitCrc   then  
      begin  
          InitCrcTable();  
          m_bInitCrc   :=   True;  
      end;  
   
      Data   :=   PByte(lpData);  
      if   (Data   =   nil)   or   (Data^   =   0)   then   Exit;  
      Result   :=   Data^   shl   24;  
      Inc(Data);  
      if   Data^   <>   0   then  
      begin  
          Result   :=   Result   or   Data^   shl   16;  
          Inc(Data);  
          if   Data^   <>   0   then  
          begin  
              Result   :=   Result   or   Data^   shl   8;  
              Inc(Data);  
              if   Data^   <>   0   then  
              begin  
                  Result   :=   Result   or   Data^;  
                  Inc(Data);  
              end;  
          end;  
      end;  
      Result   :=   not   Result;  
   
      while   Data^   <>   0   do  
      begin  
          Result   :=   (Result   shl   8   or   Data^)   xor   CrcTable[Result   shr   24];  
          Inc(data);  
      end;  
      Result   :=   not   Result;  
  end;  
   
  end.

#define   POLYNOMIAL   0x04C11DB7L //   CRC种子  
  在DELPHI里应该是多少呢?

太感谢zswang(伴水清清)(专家门诊清洁工)   了,已经OK了:)

请教:如何确保各个文件的惟一性?  
  原本打算对各个文件生成MD5校验码来区分,这对小尺寸的文件可以,但对几十M、几百M的文件而言在效率上表现很低下  
  请教:还有什么好的点子解决这种问题,谢过    
  问题贴在这里:  
  http://community.csdn.net/Expert/topic/5213/5213302.xml?temp=.5651361

posted on 2009-04-22 10:45 delphi2007 阅读(292) 评论(0)  编辑 收藏 引用
只有注册用户登录后才能发表评论。