| 1 |
unit crc_32; |
|---|
| 2 |
|
|---|
| 3 |
{ |
|---|
| 4 |
crc32.c -- compute the CRC-32 of a data stream |
|---|
| 5 |
Copyright (C) 1995-1998 Mark Adler |
|---|
| 6 |
|
|---|
| 7 |
Pascal tranlastion |
|---|
| 8 |
Copyright (C) 1998 by Jacques Nomssi Nzali |
|---|
| 9 |
|
|---|
| 10 |
Got from FreePascal 2.0.4 hash package. |
|---|
| 11 |
Modified by Sagrer (sagrer@yandex.ru) |
|---|
| 12 |
} |
|---|
| 13 |
|
|---|
| 14 |
interface |
|---|
| 15 |
|
|---|
| 16 |
type |
|---|
| 17 |
PPCardinal = ^Cardinal; |
|---|
| 18 |
|
|---|
| 19 |
function crc32(crc : cardinal; buf : Pbyte; len : cardinal) : cardinal; |
|---|
| 20 |
|
|---|
| 21 |
{ Update a running crc with the bytes buf[0..len-1] and return the updated |
|---|
| 22 |
crc. If buf is NULL, this function returns the required initial value |
|---|
| 23 |
for the crc. Pre- and post-conditioning (one's complement) is performed |
|---|
| 24 |
within this function so it shouldn't be done by the application. |
|---|
| 25 |
Usage example: |
|---|
| 26 |
|
|---|
| 27 |
var |
|---|
| 28 |
crc : cardinal; |
|---|
| 29 |
begin |
|---|
| 30 |
crc := crc32(0, nil, 0); |
|---|
| 31 |
|
|---|
| 32 |
while (read_buffer(buffer, length) <> EOF) do |
|---|
| 33 |
crc := crc32(crc, buffer, length); |
|---|
| 34 |
|
|---|
| 35 |
if (crc <> original_crc) then error(); |
|---|
| 36 |
end; |
|---|
| 37 |
|
|---|
| 38 |
} |
|---|
| 39 |
|
|---|
| 40 |
function get_crc_table : PPCardinal; { can be used by asm versions of crc32() } |
|---|
| 41 |
|
|---|
| 42 |
|
|---|
| 43 |
implementation |
|---|
| 44 |
|
|---|
| 45 |
{$IFDEF DYNAMIC_CRC_TABLE} |
|---|
| 46 |
|
|---|
| 47 |
{local} |
|---|
| 48 |
const |
|---|
| 49 |
crc_table_empty : boolean = TRUE; |
|---|
| 50 |
{local} |
|---|
| 51 |
var |
|---|
| 52 |
crc_table : array[0..256-1] of uLongf; |
|---|
| 53 |
|
|---|
| 54 |
|
|---|
| 55 |
{ |
|---|
| 56 |
Generate a table for a byte-wise 32-bit CRC calculation on the polynomial: |
|---|
| 57 |
x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. |
|---|
| 58 |
|
|---|
| 59 |
Polynomials over GF(2) are represented in binary, one bit per coefficient, |
|---|
| 60 |
with the lowest powers in the most significant bit. Then adding polynomials |
|---|
| 61 |
is just exclusive-or, and multiplying a polynomial by x is a right shift by |
|---|
| 62 |
one. If we call the above polynomial p, and represent a byte as the |
|---|
| 63 |
polynomial q, also with the lowest power in the most significant bit (so the |
|---|
| 64 |
byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, |
|---|
| 65 |
where a mod b means the remainder after dividing a by b. |
|---|
| 66 |
|
|---|
| 67 |
This calculation is done using the shift-register method of multiplying and |
|---|
| 68 |
taking the remainder. The register is initialized to zero, and for each |
|---|
| 69 |
incoming bit, x^32 is added mod p to the register if the bit is a one (where |
|---|
| 70 |
x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by |
|---|
| 71 |
x (which is shifting right by one and adding x^32 mod p if the bit shifted |
|---|
| 72 |
out is a one). We start with the highest power (least significant bit) of |
|---|
| 73 |
q and repeat for all eight bits of q. |
|---|
| 74 |
|
|---|
| 75 |
The table is simply the CRC of all possible eight bit values. This is all |
|---|
| 76 |
the information needed to generate CRC's on data a byte at a time for all |
|---|
| 77 |
combinations of CRC register values and incoming bytes. |
|---|
| 78 |
} |
|---|
| 79 |
{local} |
|---|
| 80 |
procedure make_crc_table; |
|---|
| 81 |
var |
|---|
| 82 |
c : cardinal; |
|---|
| 83 |
n,k : integer; |
|---|
| 84 |
poly : cardinal; { polynomial exclusive-or pattern } |
|---|
| 85 |
|
|---|
| 86 |
const |
|---|
| 87 |
{ terms of polynomial defining this crc (except x^32): } |
|---|
| 88 |
p: array [0..13] of Byte = (0,1,2,4,5,7,8,10,11,12,16,22,23,26); |
|---|
| 89 |
|
|---|
| 90 |
begin |
|---|
| 91 |
{ make exclusive-or pattern from polynomial ($EDB88320) } |
|---|
| 92 |
poly := longint(0); |
|---|
| 93 |
for n := 0 to (sizeof(p) div sizeof(Byte))-1 do |
|---|
| 94 |
poly := poly or (longint(1) shl (31 - p[n])); |
|---|
| 95 |
|
|---|
| 96 |
for n := 0 to 255 do |
|---|
| 97 |
begin |
|---|
| 98 |
c := cardinal(n); |
|---|
| 99 |
for k := 0 to 7 do |
|---|
| 100 |
begin |
|---|
| 101 |
if (c and 1) <> 0 then |
|---|
| 102 |
c := poly xor (c shr 1) |
|---|
| 103 |
else |
|---|
| 104 |
c := (c shr 1); |
|---|
| 105 |
end; |
|---|
| 106 |
crc_table[n] := c; |
|---|
| 107 |
end; |
|---|
| 108 |
crc_table_empty := FALSE; |
|---|
| 109 |
end; |
|---|
| 110 |
|
|---|
| 111 |
{$ELSE} |
|---|
| 112 |
|
|---|
| 113 |
{ ======================================================================== |
|---|
| 114 |
Table of CRC-32's of all single-byte values (made by make_crc_table) } |
|---|
| 115 |
|
|---|
| 116 |
{local} |
|---|
| 117 |
const |
|---|
| 118 |
crc_table : array[0..256-1] of cardinal = ( |
|---|
| 119 |
$00000000, $77073096, $ee0e612c, $990951ba, $076dc419, |
|---|
| 120 |
$706af48f, $e963a535, $9e6495a3, $0edb8832, $79dcb8a4, |
|---|
| 121 |
$e0d5e91e, $97d2d988, $09b64c2b, $7eb17cbd, $e7b82d07, |
|---|
| 122 |
$90bf1d91, $1db71064, $6ab020f2, $f3b97148, $84be41de, |
|---|
| 123 |
$1adad47d, $6ddde4eb, $f4d4b551, $83d385c7, $136c9856, |
|---|
| 124 |
$646ba8c0, $fd62f97a, $8a65c9ec, $14015c4f, $63066cd9, |
|---|
| 125 |
$fa0f3d63, $8d080df5, $3b6e20c8, $4c69105e, $d56041e4, |
|---|
| 126 |
$a2677172, $3c03e4d1, $4b04d447, $d20d85fd, $a50ab56b, |
|---|
| 127 |
$35b5a8fa, $42b2986c, $dbbbc9d6, $acbcf940, $32d86ce3, |
|---|
| 128 |
$45df5c75, $dcd60dcf, $abd13d59, $26d930ac, $51de003a, |
|---|
| 129 |
$c8d75180, $bfd06116, $21b4f4b5, $56b3c423, $cfba9599, |
|---|
| 130 |
$b8bda50f, $2802b89e, $5f058808, $c60cd9b2, $b10be924, |
|---|
| 131 |
$2f6f7c87, $58684c11, $c1611dab, $b6662d3d, $76dc4190, |
|---|
| 132 |
$01db7106, $98d220bc, $efd5102a, $71b18589, $06b6b51f, |
|---|
| 133 |
$9fbfe4a5, $e8b8d433, $7807c9a2, $0f00f934, $9609a88e, |
|---|
| 134 |
$e10e9818, $7f6a0dbb, $086d3d2d, $91646c97, $e6635c01, |
|---|
| 135 |
$6b6b51f4, $1c6c6162, $856530d8, $f262004e, $6c0695ed, |
|---|
| 136 |
$1b01a57b, $8208f4c1, $f50fc457, $65b0d9c6, $12b7e950, |
|---|
| 137 |
$8bbeb8ea, $fcb9887c, $62dd1ddf, $15da2d49, $8cd37cf3, |
|---|
| 138 |
$fbd44c65, $4db26158, $3ab551ce, $a3bc0074, $d4bb30e2, |
|---|
| 139 |
$4adfa541, $3dd895d7, $a4d1c46d, $d3d6f4fb, $4369e96a, |
|---|
| 140 |
$346ed9fc, $ad678846, $da60b8d0, $44042d73, $33031de5, |
|---|
| 141 |
$aa0a4c5f, $dd0d7cc9, $5005713c, $270241aa, $be0b1010, |
|---|
| 142 |
$c90c2086, $5768b525, $206f85b3, $b966d409, $ce61e49f, |
|---|
| 143 |
$5edef90e, $29d9c998, $b0d09822, $c7d7a8b4, $59b33d17, |
|---|
| 144 |
$2eb40d81, $b7bd5c3b, $c0ba6cad, $edb88320, $9abfb3b6, |
|---|
| 145 |
$03b6e20c, $74b1d29a, $ead54739, $9dd277af, $04db2615, |
|---|
| 146 |
$73dc1683, $e3630b12, $94643b84, $0d6d6a3e, $7a6a5aa8, |
|---|
| 147 |
$e40ecf0b, $9309ff9d, $0a00ae27, $7d079eb1, $f00f9344, |
|---|
| 148 |
$8708a3d2, $1e01f268, $6906c2fe, $f762575d, $806567cb, |
|---|
| 149 |
$196c3671, $6e6b06e7, $fed41b76, $89d32be0, $10da7a5a, |
|---|
| 150 |
$67dd4acc, $f9b9df6f, $8ebeeff9, $17b7be43, $60b08ed5, |
|---|
| 151 |
$d6d6a3e8, $a1d1937e, $38d8c2c4, $4fdff252, $d1bb67f1, |
|---|
| 152 |
$a6bc5767, $3fb506dd, $48b2364b, $d80d2bda, $af0a1b4c, |
|---|
| 153 |
$36034af6, $41047a60, $df60efc3, $a867df55, $316e8eef, |
|---|
| 154 |
$4669be79, $cb61b38c, $bc66831a, $256fd2a0, $5268e236, |
|---|
| 155 |
$cc0c7795, $bb0b4703, $220216b9, $5505262f, $c5ba3bbe, |
|---|
| 156 |
$b2bd0b28, $2bb45a92, $5cb36a04, $c2d7ffa7, $b5d0cf31, |
|---|
| 157 |
$2cd99e8b, $5bdeae1d, $9b64c2b0, $ec63f226, $756aa39c, |
|---|
| 158 |
$026d930a, $9c0906a9, $eb0e363f, $72076785, $05005713, |
|---|
| 159 |
$95bf4a82, $e2b87a14, $7bb12bae, $0cb61b38, $92d28e9b, |
|---|
| 160 |
$e5d5be0d, $7cdcefb7, $0bdbdf21, $86d3d2d4, $f1d4e242, |
|---|
| 161 |
$68ddb3f8, $1fda836e, $81be16cd, $f6b9265b, $6fb077e1, |
|---|
| 162 |
$18b74777, $88085ae6, $ff0f6a70, $66063bca, $11010b5c, |
|---|
| 163 |
$8f659eff, $f862ae69, $616bffd3, $166ccf45, $a00ae278, |
|---|
| 164 |
$d70dd2ee, $4e048354, $3903b3c2, $a7672661, $d06016f7, |
|---|
| 165 |
$4969474d, $3e6e77db, $aed16a4a, $d9d65adc, $40df0b66, |
|---|
| 166 |
$37d83bf0, $a9bcae53, $debb9ec5, $47b2cf7f, $30b5ffe9, |
|---|
| 167 |
$bdbdf21c, $cabac28a, $53b39330, $24b4a3a6, $bad03605, |
|---|
| 168 |
$cdd70693, $54de5729, $23d967bf, $b3667a2e, $c4614ab8, |
|---|
| 169 |
$5d681b02, $2a6f2b94, $b40bbe37, $c30c8ea1, $5a05df1b, |
|---|
| 170 |
$2d02ef8d); |
|---|
| 171 |
|
|---|
| 172 |
{$ENDIF} |
|---|
| 173 |
|
|---|
| 174 |
{ ========================================================================= |
|---|
| 175 |
This function can be used by asm versions of crc32() } |
|---|
| 176 |
|
|---|
| 177 |
function get_crc_table : {const} PPcardinal; |
|---|
| 178 |
begin |
|---|
| 179 |
{$ifdef DYNAMIC_CRC_TABLE} |
|---|
| 180 |
if (crc_table_empty) then |
|---|
| 181 |
make_crc_table; |
|---|
| 182 |
{$endif} |
|---|
| 183 |
get_crc_table := {const} PPcardinal(@crc_table); |
|---|
| 184 |
end; |
|---|
| 185 |
|
|---|
| 186 |
{ ========================================================================= } |
|---|
| 187 |
|
|---|
| 188 |
function crc32 (crc : cardinal; buf : Pbyte; len : cardinal): cardinal; |
|---|
| 189 |
begin |
|---|
| 190 |
if (buf = nil) then |
|---|
| 191 |
crc32 := 0 |
|---|
| 192 |
else |
|---|
| 193 |
begin |
|---|
| 194 |
|
|---|
| 195 |
{$IFDEF DYNAMIC_CRC_TABLE} |
|---|
| 196 |
if crc_table_empty then |
|---|
| 197 |
make_crc_table; |
|---|
| 198 |
{$ENDIF} |
|---|
| 199 |
|
|---|
| 200 |
crc := crc xor cardinal($ffffffff); |
|---|
| 201 |
while (len >= 8) do |
|---|
| 202 |
begin |
|---|
| 203 |
{DO8(buf)} |
|---|
| 204 |
crc := crc_table[(integer(crc) xor buf^) and $ff] xor (crc shr 8); |
|---|
| 205 |
inc(buf); |
|---|
| 206 |
crc := crc_table[(integer(crc) xor buf^) and $ff] xor (crc shr 8); |
|---|
| 207 |
inc(buf); |
|---|
| 208 |
crc := crc_table[(integer(crc) xor buf^) and $ff] xor (crc shr 8); |
|---|
| 209 |
inc(buf); |
|---|
| 210 |
crc := crc_table[(integer(crc) xor buf^) and $ff] xor (crc shr 8); |
|---|
| 211 |
inc(buf); |
|---|
| 212 |
crc := crc_table[(integer(crc) xor buf^) and $ff] xor (crc shr 8); |
|---|
| 213 |
inc(buf); |
|---|
| 214 |
crc := crc_table[(integer(crc) xor buf^) and $ff] xor (crc shr 8); |
|---|
| 215 |
inc(buf); |
|---|
| 216 |
crc := crc_table[(integer(crc) xor buf^) and $ff] xor (crc shr 8); |
|---|
| 217 |
inc(buf); |
|---|
| 218 |
crc := crc_table[(integer(crc) xor buf^) and $ff] xor (crc shr 8); |
|---|
| 219 |
inc(buf); |
|---|
| 220 |
|
|---|
| 221 |
dec(len, 8); |
|---|
| 222 |
end; |
|---|
| 223 |
if (len <> 0) then |
|---|
| 224 |
repeat |
|---|
| 225 |
{DO1(buf)} |
|---|
| 226 |
crc := crc_table[(integer(crc) xor buf^) and $ff] xor (crc shr 8); |
|---|
| 227 |
inc(buf); |
|---|
| 228 |
|
|---|
| 229 |
dec(len); |
|---|
| 230 |
until (len = 0); |
|---|
| 231 |
crc32 := crc xor cardinal($ffffffff); |
|---|
| 232 |
end; |
|---|
| 233 |
end; |
|---|
| 234 |
|
|---|
| 235 |
|
|---|
| 236 |
end. |
|---|