CRC32算法问题 Delphi / Windows SDK/APIhttp://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