[分享]实用工具三: 计算CRC的函数 ( 积分: 0 )

  • 主题发起人 Another_eYes
  • 开始时间
A

Another_eYes

Unregistered / Unconfirmed
GUEST, unregistred user!
unit导出了三个函数:

function CalcCRC32(const buf; Len: Cardinal): Cardinal;
计算某块buffer的CRC32值

function CalcFileCRC32(const FileName: string; FSize: PCardinal = nil): Cardinal;
计算某个文件的CRC32值(分块读取,每次4M,针对大文件计算可以减小程序资源消耗)
FSize如果<>nil则文件大小将返回在FSize指向的变量中

procedure ContinueCRC32(var CRC: Cardinal; const buf; Len: Cardinal);
根据上一块buffer的CRC32值继续计算加上本块buffer后的CRC32值

unit CRCUnit;

interface

uses
SysUtils, Windows;

function CalcCRC32(const buf; Len: Cardinal): Cardinal;
function CalcFileCRC32(const FileName: string; FSize: PCardinal = nil): Cardinal;
procedure ContinueCRC32(var CRC: Cardinal; const buf; Len: Cardinal);

const
CRC32_POLYNOMIAL = $EDB88320;
MAX_BUFFER_SIZE = 4*1024*1024;

var
Ccitt32Table: array[0..255] of DWORD;

implementation

procedure BuildCRCTable;
var i, j: longint;
value: DWORD;
begin
for i := 0 to 255 do begin
value := i;
for j := 8 downto 1 do
if ((value and 1) <> 0) then
value := (value shr 1) xor CRC32_POLYNOMIAL
else
value := value shr 1;
Ccitt32Table := value;
end
end;

function CalcCRC32(const buf; Len: Cardinal): Cardinal;
var
j: Cardinal;
p: PByte;
begin
Result:=$FFFFFFFF;
if len <= 0 then exit;
p := PByte(@buf);
for j:=1 to Len do
begin
result := (((result shr 8) and $00FFFFFF) xor (Ccitt32Table[(result xor p^) and $FF]));
inc(p);
end;
end;

procedure ContinueCRC32(var CRC: Cardinal; const buf; Len: Cardinal);
var
j: Cardinal;
p: PByte;
begin
p := PByte(@buf);
for j:=1 to Len do
begin
CRC := (((CRC shr 8) and $00FFFFFF) xor (Ccitt32Table[(CRC xor p^) and $FF]));
inc(p);
end;
end;

function CalcFileCRC32(const FileName: string; FSize: PCardinal = nil): Cardinal;
var
FileHandle: THandle;
//MapHandle: THandle;
//ViewPointer: pointer;
sz, rsz: Cardinal;
tmp: string;
begin
result := $FFFFFFFF;
if not fileexists(filename) then exit;
//try
FileHandle := CreateFile(pChar(FileName), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
if FileHandle <> INVALID_HANDLE_VALUE then
try
sz := GetFileSize(FileHandle, nil);
if fsize<>nil then
fsize^ := sz;
setlength(tmp, MAX_BUFFER_SIZE);
while sz > 0 do
begin
if sz > MAX_BUFFER_SIZE then rsz := MAX_BUFFER_SIZE else rsz := sz;
fileread(filehandle, tmp[1], rsz);
continuecrc32(result, tmp[1], rsz);
dec(sz, rsz);
end;
{MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
if MapHandle <> 0 then
try
ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
if ViewPointer <> nil then
try
result := calcCRC32(ViewPointer^, sz, fprogress);
finally
UnmapViewOfFile(ViewPointer);
end;
finally
closehandle(MapHandle);
end;}
finally
CloseHandle(FileHandle);
end;
//except
//end;
end;

initialization
BuildCRCTable;

end.
 
unit导出了三个函数:

function CalcCRC32(const buf; Len: Cardinal): Cardinal;
计算某块buffer的CRC32值

function CalcFileCRC32(const FileName: string; FSize: PCardinal = nil): Cardinal;
计算某个文件的CRC32值(分块读取,每次4M,针对大文件计算可以减小程序资源消耗)
FSize如果<>nil则文件大小将返回在FSize指向的变量中

procedure ContinueCRC32(var CRC: Cardinal; const buf; Len: Cardinal);
根据上一块buffer的CRC32值继续计算加上本块buffer后的CRC32值

unit CRCUnit;

interface

uses
SysUtils, Windows;

function CalcCRC32(const buf; Len: Cardinal): Cardinal;
function CalcFileCRC32(const FileName: string; FSize: PCardinal = nil): Cardinal;
procedure ContinueCRC32(var CRC: Cardinal; const buf; Len: Cardinal);

const
CRC32_POLYNOMIAL = $EDB88320;
MAX_BUFFER_SIZE = 4*1024*1024;

var
Ccitt32Table: array[0..255] of DWORD;

implementation

procedure BuildCRCTable;
var i, j: longint;
value: DWORD;
begin
for i := 0 to 255 do begin
value := i;
for j := 8 downto 1 do
if ((value and 1) <> 0) then
value := (value shr 1) xor CRC32_POLYNOMIAL
else
value := value shr 1;
Ccitt32Table := value;
end
end;

function CalcCRC32(const buf; Len: Cardinal): Cardinal;
var
j: Cardinal;
p: PByte;
begin
Result:=$FFFFFFFF;
if len <= 0 then exit;
p := PByte(@buf);
for j:=1 to Len do
begin
result := (((result shr 8) and $00FFFFFF) xor (Ccitt32Table[(result xor p^) and $FF]));
inc(p);
end;
end;

procedure ContinueCRC32(var CRC: Cardinal; const buf; Len: Cardinal);
var
j: Cardinal;
p: PByte;
begin
p := PByte(@buf);
for j:=1 to Len do
begin
CRC := (((CRC shr 8) and $00FFFFFF) xor (Ccitt32Table[(CRC xor p^) and $FF]));
inc(p);
end;
end;

function CalcFileCRC32(const FileName: string; FSize: PCardinal = nil): Cardinal;
var
FileHandle: THandle;
//MapHandle: THandle;
//ViewPointer: pointer;
sz, rsz: Cardinal;
tmp: string;
begin
result := $FFFFFFFF;
if not fileexists(filename) then exit;
//try
FileHandle := CreateFile(pChar(FileName), GENERIC_READ, FILE_SHARE_READ or FILE_SHARE_WRITE,
nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, 0);
if FileHandle <> INVALID_HANDLE_VALUE then
try
sz := GetFileSize(FileHandle, nil);
if fsize<>nil then
fsize^ := sz;
setlength(tmp, MAX_BUFFER_SIZE);
while sz > 0 do
begin
if sz > MAX_BUFFER_SIZE then rsz := MAX_BUFFER_SIZE else rsz := sz;
fileread(filehandle, tmp[1], rsz);
continuecrc32(result, tmp[1], rsz);
dec(sz, rsz);
end;
{MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
if MapHandle <> 0 then
try
ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
if ViewPointer <> nil then
try
result := calcCRC32(ViewPointer^, sz, fprogress);
finally
UnmapViewOfFile(ViewPointer);
end;
finally
closehandle(MapHandle);
end;}
finally
CloseHandle(FileHandle);
end;
//except
//end;
end;

initialization
BuildCRCTable;

end.
 
好呀! 叫一声,顶一下。收藏
 
没辙了,只好来追着高手来问了,呵呵。

Another_eYes大侠,能否帮我看看
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3258855
谢谢啦!
 

Similar threads

I
回复
0
查看
780
import
I
I
回复
0
查看
638
import
I
I
回复
0
查看
733
import
I
I
回复
0
查看
690
import
I
顶部