CRC32的算法
软件需要实现以下几个功能,这些功能整合在一个软件中。
1、待计算数据串输入
待计算数据串在软件界面中输入。
待计算数据串由多个字节(16进制表示,总长度不固定)组成(ep:0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07),用户软件应提供一个友好的界面,实现待计算数据串的输入。
2、CRC32校验值计算
根据CRC32标准算法对输入数据串进行计算,生成输入数据串的CRC32检验码,生成多项式为:
X32+X30+ X27 +X25+X22+X20+X13+X12+X11+X10+X8+X7+X6+X5+X4+X0
检验码初始值为0x00FF0000。
3、计算结果显示
软件界面应能显示最终的CRC32检验码。
以上是需求,关键是如何用代码来实现CRC32的计算,请教高手。
[解决办法]
http://blog.csdn.net/ksaiy/archive/2004/12/23/226960.aspx
[解决办法]
crc32单元文件。。。
- Delphi(Pascal) code
unit Crc32;interfaceuses Windows;function ComputeFileCRC32(const FileName : String) : DWORD;function UpdateCRC32(InitCRC : DWORD; BufPtr : Pointer; Len : Word) : LongInt;implementationtype CRCTable = array [0..255] of DWORD;const BufLen = 32768; CRC32Table : CRCTable = ($00000000, $77073096, $ee0e612c, $990951ba, $076dc419, $706af48f, $e963a535, $9e6495a3, $0edb8832, $79dcb8a4, $e0d5e91e, $97d2d988, $09b64c2b, $7eb17cbd, $e7b82d07, $90bf1d91, $1db71064, $6ab020f2, $f3b97148, $84be41de, $1adad47d, $6ddde4eb, $f4d4b551, $83d385c7, $136c9856, $646ba8c0, $fd62f97a, $8a65c9ec, $14015c4f, $63066cd9, $fa0f3d63, $8d080df5, $3b6e20c8, $4c69105e, $d56041e4, $a2677172, $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b, $35b5a8fa, $42b2986c, $dbbbc9d6, $acbcf940, $32d86ce3, $45df5c75, $dcd60dcf, $abd13d59, $26d930ac, $51de003a, $c8d75180, $bfd06116, $21b4f4b5, $56b3c423, $cfba9599, $b8bda50f, $2802b89e, $5f058808, $c60cd9b2, $b10be924, $2f6f7c87, $58684c11, $c1611dab, $b6662d3d, $76dc4190, $01db7106, $98d220bc, $efd5102a, $71b18589, $06b6b51f, $9fbfe4a5, $e8b8d433, $7807c9a2, $0f00f934, $9609a88e, $e10e9818, $7f6a0dbb, $086d3d2d, $91646c97, $e6635c01, $6b6b51f4, $1c6c6162, $856530d8, $f262004e, $6c0695ed, $1b01a57b, $8208f4c1, $f50fc457, $65b0d9c6, $12b7e950, $8bbeb8ea, $fcb9887c, $62dd1ddf, $15da2d49, $8cd37cf3, $fbd44c65, $4db26158, $3ab551ce, $a3bc0074, $d4bb30e2, $4adfa541, $3dd895d7, $a4d1c46d, $d3d6f4fb, $4369e96a, $346ed9fc, $ad678846, $da60b8d0, $44042d73, $33031de5, $aa0a4c5f, $dd0d7cc9, $5005713c, $270241aa, $be0b1010, $c90c2086, $5768b525, $206f85b3, $b966d409, $ce61e49f, $5edef90e, $29d9c998, $b0d09822, $c7d7a8b4, $59b33d17, $2eb40d81, $b7bd5c3b, $c0ba6cad, $edb88320, $9abfb3b6, $03b6e20c, $74b1d29a, $ead54739, $9dd277af, $04db2615, $73dc1683, $e3630b12, $94643b84, $0d6d6a3e, $7a6a5aa8, $e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1, $f00f9344, $8708a3d2, $1e01f268, $6906c2fe, $f762575d, $806567cb, $196c3671, $6e6b06e7, $fed41b76, $89d32be0, $10da7a5a, $67dd4acc, $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5, $d6d6a3e8, $a1d1937e, $38d8c2c4, $04fdff252, $d1bb67f1, $a6bc5767, $3fb506dd, $048b2364b, $d80d2bda, $af0a1b4c, $36034af6, $041047a60, $df60efc3, $a867df55, $316e8eef, $04669be79, $cb61b38c, $bc66831a, $256fd2a0, $5268e236, $cc0c7795, $bb0b4703, $220216b9, $5505262f, $c5ba3bbe, $b2bd0b28, $2bb45a92, $5cb36a04, $c2d7ffa7, $b5d0cf31, $2cd99e8b, $5bdeae1d, $9b64c2b0, $ec63f226, $756aa39c, $026d930a, $9c0906a9, $eb0e363f, $72076785, $05005713, $95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38, $92d28e9b, $e5d5be0d, $7cdcefb7, $0bdbdf21, $86d3d2d4, $f1d4e242, $68ddb3f8, $1fda836e, $81be16cd, $f6b9265b, $6fb077e1, $18b74777, $88085ae6, $ff0f6a70, $66063bca, $11010b5c, $8f659eff, $f862ae69, $616bffd3, $166ccf45, $a00ae278, $d70dd2ee, $4e048354, $3903b3c2, $a7672661, $d06016f7, $4969474d, $3e6e77db, $aed16a4a, $d9d65adc, $40df0b66, $37d83bf0, $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9, $bdbdf21c, $cabac28a, $53b39330, $24b4a3a6, $bad03605, $cdd70693, $54de5729, $23d967bf, $b3667a2e, $c4614ab8, $5d681b02, $2a6f2b94, $b40bbe37, $c30c8ea1, $5a05df1b, $2d02ef8d);var Buf : array [1..BufLen] of Byte;function UpdateCRC32(InitCRC : DWORD; BufPtr : Pointer; Len : Word) : LongInt;var crc : DWORD; index : Integer; i : DWORD;begin crc := InitCRC; for i:=0 to Len-1 do begin index := (crc xor DWORD(Pointer(DWORD(BufPtr)+i)^)) and $000000FF; crc := ((crc shr 8) and $00FFFFFF) xor CRC32Table[index]; end; Result := crc;end;function ComputeFileCRC32(const FileName : String) : DWORD;var InFile : file; crc32 : DWORD; Res : Integer; BufPtr : Pointer; OldFM : Byte;begin BufPtr := @Buf; OldFM := FileMode; FileMode := 0; Assign(InFile,FileName); Reset(InFile,1); crc32 := $FFFFFFFF; repeat BlockRead(InFile,Buf,BufLen,Res); crc32 := UpdateCrc32(crc32,BufPtr,Res); until Eof(InFile); Close(InFile); FileMode := OldFM; crc32 := not crc32; Result := crc32;end;end.
[解决办法]
[code=C]/C++
template <typename valueType>
class crc
{
private:
/// <summary>
/// CRC查询表
/// </summary>
valueType Crcs[256];
public:
/// <summary>
/// 初始化CRC查询表
/// </summary>
/// <param name="code">多项式值(不包含第一个2进制0) </param>
crc(valueType code)
{
set(code);
}
/// <summary>
/// 根据多项式值生成查询表
/// </summary>
/// <param name="code">多项式值(不包含第一个2进制0) </param>
void set(valueType code)
{
valueType value;
for (byte bit, index = 255; index != 0; --index)
{
for (value = index, bit = 8; bit != 0; --bit)
{
if ((value & 1) == 1) value = (value >> 1) ^ code;
else value >>= 1;
}
Crcs[index] = value;
}
Crcs[0] = 0;
}
/// <summary>
/// 计算CRC检验值
/// </summary>
/// <param name="value">CRC检验值 </param>
/// <param name="data">数据地址 </param>
/// <param name="length">数据临时量 </param>
#ifdef PLATFORM_64BIT
#define CRC(value, data, dataValue) dataValue = *(uint*)(data);\
value = Crcs[(byte)(value ^ dataValue)] ^ (value >> 8);\
value = Crcs[(byte)(value ^ (dataValue >>= 8))] ^ (value >> 8);\
value = Crcs[(byte)(value ^ (dataValue >>= 8))] ^ (value >> 8);\
value = Crcs[(byte)(value ^ (dataValue >>= 8))] ^ (value >> 8);\
value = Crcs[(byte)(value ^ (dataValue >>= 8))] ^ (value >> 8);\
value = Crcs[(byte)(value ^ (dataValue >>= 8))] ^ (value >> 8);\
value = Crcs[(byte)(value ^ (dataValue >>= 8))] ^ (value >> 8);\
value = Crcs[(byte)(value ^ (dataValue >>= 8))] ^ (value >> 8);
#else
#define CRC(value, data, dataValue) dataValue = *(uint*)(data);\
value = Crcs[(byte)(value ^ dataValue)] ^ (value >> 8);\
value = Crcs[(byte)(value ^ (dataValue >>= 8))] ^ (value >> 8);\
value = Crcs[(byte)(value ^ (dataValue >>= 8))] ^ (value >> 8);\
value = Crcs[(byte)(value ^ (dataValue >>= 8))] ^ (value >> 8);
#endif
/// <summary>
/// 获取CRC检验值
/// </summary>
/// <param name="data">数据 </param>
/// <param name="length">数据长度 </param>
/// <returns>CRC检验值 </returns>
valueType get(byte *data, int32 length)
{
if(data == NULL && length <= 0) throw showjim::sys::exception::indexOverflow;
uint dataValue;
valueType value = (valueType)UINTBYTE(ff);
byte right = (byte)data & (CPUBYTE - 1);
if(right != 0)
{
dataValue = *(uint*)(data - right) >> (right < < 3);
byte left = CPUBYTE - right;
data += left;
if(left >= length)
{
left = length;
length = 0;
}
else length -= left;
do
{
value = Crcs[(byte)(value ^ (valueType)dataValue)] ^ (value >> 8);
dataValue >>= 8;
}
while(--left != 0);
}
right = length & (CPUBIT - 1);
for(byte *end = data + length - right; data != end; data += CPUBIT)
{
CRC(value, data, dataValue);
CRC(value, data + CPUBYTE, dataValue);
CRC(value, data + CPUBYTE * 2, dataValue);
CRC(value, data + CPUBYTE * 3, dataValue);
CRC(value, data + CPUBYTE * 4, dataValue);
CRC(value, data + CPUBYTE * 5, dataValue);
CRC(value, data + CPUBYTE * 6, dataValue);
CRC(value, data + CPUBYTE * 7, dataValue);
}
if((right & (CPUBIT >> 1)) != 0)
{
CRC(value, data, dataValue);
CRC(value, data + CPUBYTE, dataValue);
CRC(value, data + CPUBYTE * 2, dataValue);
CRC(value, data + CPUBYTE * 3, dataValue);
data += CPUBIT >> 1;
}
if((right & (CPUBIT >> 2)) != 0)
{
CRC(value, data, dataValue);
CRC(value, data + CPUBYTE, dataValue);
data += CPUBIT >> 2;
}
if((right & (CPUBIT >> 3)) != 0)
{
CRC(value, data, dataValue);
data += CPUBIT >> 3;
}
if((right &= (CPUBYTE - 1)) != 0)
{
dataValue = *(uint*)data;
do
{
value = Crcs[(byte)(value ^ dataValue)] ^ (value >> 8);
dataValue >>= 8;
}
while(--right != 0);
}
return ~value;
}
/// <summary>
/// 获取CRC检验值
/// </summary>
/// <param name="code">多项式值(不包含第一个2进制0) </param>
/// <param name="data">数据 </param>
/// <param name="length">数据长度 </param>
/// <returns>CRC检验值 </returns>
inline static valueType value(valueType code, byte *data, int32 length)
{
return crc(code).get(data, length);
}
};
[/code]
get函数简单的写,其实就是一个个字节读的循环
[code=C]/C++
uint32 get(byte *data, int32 length)
{
uint32 value = 0xffffffffUL;
for(byte *end = data + length; data != end; ++data) value = Crcs[(byte)(value ^ *data)] ^ (value >> 8);
return ~value;
}
[/code]
[解决办法]
某世界级软件公司泄露代码中的CRC32实现。把公司名称去了,看代码风格应该知道是哪家。
/*++
Module Name:
crc32.h
Abstract:
CRC-32 alogorithm prototypes and constants
--*/
//////////////////////////////////////////////////////////////
//
// Function prototypes for CRC-32
//
//////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C"
{
#endif
void
Crc32( unsigned long crc,
unsigned long cbBuffer,
void * pvBuffer,
unsigned long * pNewCrc);
#ifdef __cplusplus
}
#endif
/*++
Module Name:
crc32.c
Abstract:
CRC-32 alogorithm
31-Mar-94 MikeSw Created
25-Jul-96 ChandanS Copied from net\svcdlls\ntlmssp\client\crc32.c
27-Jan-07 MikeSw Incorporated x86 ASM code for performance
--*/
#include "crc32.h"
#ifdef KMODE_NTLM
#ifdef ALLOC_PRAGMA
#pragma alloc_text("PAGEMSG", Crc32)
#endif // ALLOC_PRAGMA
#endif // KMODE
//
// This code comes from Dr. Dobbs Journal, May 1992
//
unsigned long CRCTable[256] = {
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 };
void
Crc32( unsigned long dwCrc,
unsigned long cbBuffer,
void * pvBuffer,
unsigned long * pNewCrc)
{
unsigned char * pbBuffer;
#ifdef _X86_
_asm
{
mov ecx, DWORD PTR cbBuffer
shr ecx, 2
mov eax, ecx
dec ecx
mov esi, DWORD PTR pvBuffer
mov edx, DWORD PTR dwCrc
test eax, eax
je SHORT $LABEL2
inc ecx
$LABEL1:
mov ebx, DWORD PTR [esi]
add esi, 4
mov eax, ebx
shr ebx, 8
xor eax, edx
and eax, 0FFh
shr edx, 8
mov edi, DWORD PTR CRCTable[eax*4]
xor edx, edi
mov eax, ebx
shr ebx, 8
xor eax, edx
and eax, 0FFh
shr edx, 8
mov edi, DWORD PTR CRCTable[eax*4]
xor edx, edi
mov eax, ebx
shr ebx, 8
xor eax, edx
and eax, 0FFh
shr edx, 8
mov edi, DWORD PTR CRCTable[eax*4]
xor edx, edi
mov eax, ebx
; shr ebx, 8 -- Not needed on last byte
xor eax, edx
and eax, 0FFh
shr edx, 8
mov edi, DWORD PTR CRCTable[eax*4]
xor edx, edi
dec ecx
jne SHORT $LABEL1
$LABEL2:
mov DWORD PTR dwCrc, edx
mov DWORD PTR pbBuffer, esi
}
cbBuffer &= 0x3;
#else // _X86_
pbBuffer = (unsigned char *) pvBuffer;
#endif
while (cbBuffer-- != 0)
{
dwCrc = (dwCrc >> 8) ^ CRCTable[(unsigned char) dwCrc ^ *pbBuffer++];
}
*pNewCrc = dwCrc;
}
[解决办法]
我百度的不是很懂!希望对你有帮助
下面是产生CRC-32校验吗的子程序。
unsigned long crc_32_tab[256]={
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,0x0edb8832,…, 0x5a05df1b, 0x2d02ef8d
};//事先计算出的参数表,共有256项,未全部列出。
unsigned long GenerateCRC32(char xdata * DataBuf,unsigned long len)
{
unsigned long oldcrc32;
unsigned long crc32;
unsigned long oldcrc;
unsigned int charcnt;
char c,t;
oldcrc32 = 0x00000000; //初值为0
charcnt=0;
while (len--) {
t= (oldcrc32 >> 24) & 0xFF; //要移出的字节的值
oldcrc=crc_32_tab[t]; //根据移出的字节的值查表
c=DataBuf[charcnt]; //新移进来的字节值
oldcrc32= (oldcrc32 << 8) | c; //将新移进来的字节值添在寄存器末字节中
oldcrc32=oldcrc32^oldcrc; //将寄存器与查出的值进行xor运算
charcnt++;
}
crc32=oldcrc32;
return crc32;
}
参数表可以先在PC机上算出来,也可在程序初始化时完成。下面是用于计算参数表的c语言子程序,在Visual C++ 6.0下编译通过。
#include <stdio.h>
unsigned long int crc32_table[256];
unsigned long int ulPolynomial = 0x04c11db7;
unsigned long int Reflect(unsigned long int ref, char ch)
{ unsigned long int value(0);
// 交换bit0和bit7,bit1和bit6,类推
for(int i = 1; i < (ch + 1); i++)
{ if(ref & 1)
value |= 1 << (ch - i);
ref >>= 1; }
return value;
}
init_crc32_table()
{ unsigned long int crc,temp;
// 256个值
for(int i = 0; i <= 0xFF; i++)
{ temp=Reflect(i, 8);
crc32_table[i]= temp<< 24;
for (int j = 0; j < 8; j++){
unsigned long int t1,t2;
unsigned long int flag=crc32_table[i]&0x80000000;
t1=(crc32_table[i] << 1);
if(flag==0)
t2=0;
else
t2=ulPolynomial;
crc32_table[i] =t1^t2 ; }
crc=crc32_table[i];
crc32_table[i] = Reflect(crc32_table[i], 32);
}
}
[解决办法]
- Delphi(Pascal) code
unit CRC32;{32 Bit CRC, polynomial (used in Zip and others)}interface(************************************************************************* DESCRIPTION : 32 Bit CRC REQUIREMENTS : D4-D7/D9-D10/D12, FPC EXTERNAL DATA : --- MEMORY USAGE : --- DISPLAY MODE : --- REFERENCES : --- Version Date Author Modification ------- -------- ------- ------------------------------------------ 0.10 29.09.07 W.Ehrhardt Initial version based on standard v3.07 0.11 12.11.08 we uses BTypes, Ptr2Inc and/or Str255/Str127 0.12 19.07.09 we D12 fix: assign with typecast string(fname)**************************************************************************)(*------------------------------------- (C) Copyright 2002-2009 Wolfgang Ehrhardt This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution.----------------------------------------*){$i STD.INC}uses BTypes;procedure CRC32Init(var CRC: longint); {-initialize context} {$ifdef DLL} stdcall; {$endif}procedure CRC32Update(var CRC: longint; Msg: pointer; Len: word); {-update CRC32 with Msg data} {$ifdef DLL} stdcall; {$endif}procedure CRC32Final(var CRC: longint); {-CRC32: finalize calculation} {$ifdef DLL} stdcall; {$endif}function CRC32SelfTest: boolean; {-Self test for CRC32} {$ifdef DLL} stdcall; {$endif}procedure CRC32Full(var CRC: longint; Msg: pointer; Len: word); {-CRC32 of Msg with init/update/final} {$ifdef DLL} stdcall; {$endif}procedure CRC32File(const fname: Str255; var CRC: longint; var buf; bsize: word; var Err: word); {-CRC32 of file, buf: buffer with at least bsize bytes} {$ifdef DLL} stdcall; {$endif}procedure CRC32UpdateXL(var CRC: longint; Msg: pointer; Len: longint); {-update CRC32 with Msg data} {$ifdef DLL} stdcall; {$endif}procedure CRC32FullXL(var CRC: longint; Msg: pointer; Len: longint); {-CRC32 of Msg with init/update/final} {$ifdef DLL} stdcall; {$endif}implementationconst Mask32 = longint($FFFFFFFF);{$ifdef StrictLong} {$warnings off} {$R-} {avoif D9 errors!}{$endif}const CTab: array[0..255] of longint = ( $00000000,$77073096,$ee0e612c,$990951ba,$076dc419,$706af48f,$e963a535,$9e6495a3, $0edb8832,$79dcb8a4,$e0d5e91e,$97d2d988,$09b64c2b,$7eb17cbd,$e7b82d07,$90bf1d91, $1db71064,$6ab020f2,$f3b97148,$84be41de,$1adad47d,$6ddde4eb,$f4d4b551,$83d385c7, $136c9856,$646ba8c0,$fd62f97a,$8a65c9ec,$14015c4f,$63066cd9,$fa0f3d63,$8d080df5, $3b6e20c8,$4c69105e,$d56041e4,$a2677172,$3c03e4d1,$4b04d447,$d20d85fd,$a50ab56b, $35b5a8fa,$42b2986c,$dbbbc9d6,$acbcf940,$32d86ce3,$45df5c75,$dcd60dcf,$abd13d59, $26d930ac,$51de003a,$c8d75180,$bfd06116,$21b4f4b5,$56b3c423,$cfba9599,$b8bda50f, $2802b89e,$5f058808,$c60cd9b2,$b10be924,$2f6f7c87,$58684c11,$c1611dab,$b6662d3d, $76dc4190,$01db7106,$98d220bc,$efd5102a,$71b18589,$06b6b51f,$9fbfe4a5,$e8b8d433, $7807c9a2,$0f00f934,$9609a88e,$e10e9818,$7f6a0dbb,$086d3d2d,$91646c97,$e6635c01, $6b6b51f4,$1c6c6162,$856530d8,$f262004e,$6c0695ed,$1b01a57b,$8208f4c1,$f50fc457, $65b0d9c6,$12b7e950,$8bbeb8ea,$fcb9887c,$62dd1ddf,$15da2d49,$8cd37cf3,$fbd44c65, $4db26158,$3ab551ce,$a3bc0074,$d4bb30e2,$4adfa541,$3dd895d7,$a4d1c46d,$d3d6f4fb, $4369e96a,$346ed9fc,$ad678846,$da60b8d0,$44042d73,$33031de5,$aa0a4c5f,$dd0d7cc9, $5005713c,$270241aa,$be0b1010,$c90c2086,$5768b525,$206f85b3,$b966d409,$ce61e49f, $5edef90e,$29d9c998,$b0d09822,$c7d7a8b4,$59b33d17,$2eb40d81,$b7bd5c3b,$c0ba6cad, $edb88320,$9abfb3b6,$03b6e20c,$74b1d29a,$ead54739,$9dd277af,$04db2615,$73dc1683, $e3630b12,$94643b84,$0d6d6a3e,$7a6a5aa8,$e40ecf0b,$9309ff9d,$0a00ae27,$7d079eb1, $f00f9344,$8708a3d2,$1e01f268,$6906c2fe,$f762575d,$806567cb,$196c3671,$6e6b06e7, $fed41b76,$89d32be0,$10da7a5a,$67dd4acc,$f9b9df6f,$8ebeeff9,$17b7be43,$60b08ed5, $d6d6a3e8,$a1d1937e,$38d8c2c4,$4fdff252,$d1bb67f1,$a6bc5767,$3fb506dd,$48b2364b, $d80d2bda,$af0a1b4c,$36034af6,$41047a60,$df60efc3,$a867df55,$316e8eef,$4669be79, $cb61b38c,$bc66831a,$256fd2a0,$5268e236,$cc0c7795,$bb0b4703,$220216b9,$5505262f, $c5ba3bbe,$b2bd0b28,$2bb45a92,$5cb36a04,$c2d7ffa7,$b5d0cf31,$2cd99e8b,$5bdeae1d, $9b64c2b0,$ec63f226,$756aa39c,$026d930a,$9c0906a9,$eb0e363f,$72076785,$05005713, $95bf4a82,$e2b87a14,$7bb12bae,$0cb61b38,$92d28e9b,$e5d5be0d,$7cdcefb7,$0bdbdf21, $86d3d2d4,$f1d4e242,$68ddb3f8,$1fda836e,$81be16cd,$f6b9265b,$6fb077e1,$18b74777, $88085ae6,$ff0f6a70,$66063bca,$11010b5c,$8f659eff,$f862ae69,$616bffd3,$166ccf45, $a00ae278,$d70dd2ee,$4e048354,$3903b3c2,$a7672661,$d06016f7,$4969474d,$3e6e77db, $aed16a4a,$d9d65adc,$40df0b66,$37d83bf0,$a9bcae53,$debb9ec5,$47b2cf7f,$30b5ffe9, $bdbdf21c,$cabac28a,$53b39330,$24b4a3a6,$bad03605,$cdd70693,$54de5729,$23d967bf, $b3667a2e,$c4614ab8,$5d681b02,$2a6f2b94,$b40bbe37,$c30c8ea1,$5a05df1b,$2d02ef8d);{$ifdef StrictLong} {$warnings on} {$ifdef RangeChecks_on} {$R+} {$endif}{$endif}{---------------------------------------}procedure CRC32Update(var CRC: longint; Msg: pointer; Len: word); {-update CRC32 with Msg data}begin CRC32UpdateXL(CRC, Msg, Len);end;{---------------------------------------}procedure CRC32UpdateXL(var CRC: longint; Msg: pointer; Len: longint); {-update CRC32 with Msg data}var i: longint;begin for i:=1 to Len do begin CRC := CTab[byte(CRC) xor PByte(Msg)^] xor (CRC shr 8); inc(Ptr2Inc(Msg)); end;end;{---------------------------------------}procedure CRC32FullXL(var CRC: longint; Msg: pointer; Len: longint); {-CRC32 of Msg with init/update/final}begin CRC32Init(CRC); CRC32UpdateXL(CRC, Msg, Len); CRC32Final(CRC);end;{---------------------------------------}procedure CRC32Init(var CRC: longint); {-CRC initialization}begin CRC := Mask32;end;{---------------------------------------}procedure CRC32Final(var CRC: longint); {-CRC32: finalize calculation}begin CRC := CRC xor Mask32;end;{---------------------------------------}procedure CRC32Full(var CRC: longint; Msg: pointer; Len: word); {-CRC32 of Msg with init/update/final}begin CRC32Init(CRC); CRC32Update(CRC, Msg, Len); CRC32Final(CRC);end;{---------------------------------------}function CRC32SelfTest: boolean; {-self test for CRC32}const s: string[17] = '0123456789abcdefg'; Check = longint($BE6CBE90);var i: integer; CRC, CRCF: longint;begin CRC32Full(CRCF, @s[1], length(s)); CRC32Init(CRC); for i:=1 to length(s) do CRC32Update(CRC, @s[i], 1); CRC32Final(CRC); CRC32SelfTest := (CRC=Check) and (CRCF=Check);end;{$i-} {Force I-}{---------------------------------------}procedure CRC32File(const fname: Str255; var CRC: longint; var buf; bsize: word; var Err: word); {-CRC32 of file, buf: buffer with at least bsize bytes}var fms: byte; L: longint; f: file;begin fms := FileMode; FileMode := 0; system.assign(f,{$ifdef D12Plus} string {$endif} (fname)); system.reset(f,1); Err := IOResult; FileMode := fms; if Err<>0 then exit; CRC32Init(CRC); L := bsize; while (Err=0) and (L=bsize) do begin system.blockread(f,buf,bsize,L); Err := IOResult; CRC32UpdateXL(CRC, @buf, L); end; system.close(f); if IOResult=0 then; CRC32Final(CRC);end;end.