home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 November / Chip_2002-11_cd1.bin / zkuste / delphi / unity / d4567 / FIPCRC.ZIP / CRC.pas
Pascal/Delphi Source File  |  2002-08-15  |  6KB  |  380 lines

  1. {
  2.  
  3. *** Universal CRC ***
  4. *** by Filip Skalka, fip@post.cz ***
  5. *** August 2002 ***
  6.  
  7. Supported bit width: 8,16,24,32,...,256 (stepped by 8 bits)
  8.  
  9. Polynom - Direct mathematical formula without msb bit.
  10.           eg. [0,4,5] means x^8+x^5+x^4+x^0
  11.  
  12. ByteWidth - Width of CRC in bytes. Range : [1,32]
  13.  
  14. Masked - Fill initial value of CRC by $FF... and xor output value by $FF... too.
  15.  
  16.  
  17. Usage:
  18.  
  19. var
  20.     x,y:longword;
  21.     CRC:TCRC;
  22.     CRC8:TCRC8;
  23. begin
  24.  CRC:=TCRC.Create([0,1,2,4,5,7,8,10,11,12,16,22,23,26],4);
  25.  x:=1;
  26.  y:=0;
  27.  CRC.CalculateCRC(x,y,4);
  28.  
  29.  CRC8:=TCRC8.Create;
  30.  x:=1;
  31.  y:=0;
  32.  CRC8.CalculateCRC(x,y,1);
  33. end;
  34.  
  35. }
  36. unit CRC;
  37. interface
  38.  
  39. type
  40.  TPolynom=set of byte;
  41.  
  42.  TCRC=class
  43.  private
  44.   FByteWidth:cardinal;
  45.   FTable:array of byte;
  46.   FMasked:boolean;
  47.   FPolynom:TPolynom;
  48.  protected
  49.   procedure SetMasked(const AValue:boolean);
  50.  public
  51.   constructor Create(const APolynom:TPolynom;const AByteWidth:cardinal);
  52.  
  53.   property ByteWidth:cardinal read FByteWidth;
  54.   property Polynom:TPolynom read FPolynom;
  55.   property Masked:boolean read FMasked write SetMasked;
  56.  
  57.   procedure CalculateCRC(var Buffer;var Result;const BufferSize:integer);
  58.  end;
  59.  
  60.  TCRC8=class(TCRC)
  61.  public
  62.   constructor Create;
  63.  end;
  64.  
  65.  TCRC16=class(TCRC)
  66.  public
  67.   constructor Create;
  68.  end;
  69.  
  70.  TCRC24=class(TCRC)
  71.  public
  72.   constructor Create;
  73.  end;
  74.  
  75.  TCRC32=class(TCRC)
  76.  public
  77.   constructor Create;
  78.  end;
  79.  
  80.  TCTC64=class(TCRC)
  81.  public
  82.   constructor Create;
  83.  end;
  84.  
  85. implementation
  86.  
  87. type
  88.  TEntry=array [0..31] of byte;
  89.  PByteArray=^TByteArray;
  90.  TByteArray=array [0..999] of byte;
  91.  
  92. procedure ReverseBits(var buffer;const Size:longword);
  93. asm
  94.  push esi
  95.  push edi
  96.  
  97.  mov esi,eax
  98.  lea edi,esi+edx-1
  99.  mov ecx,edx
  100.  
  101.  shr ecx,1
  102.  adc ecx,0
  103.  
  104. @Loop:
  105.  jecxz @End
  106.  mov al,[esi]
  107.  mov ah,[edi]
  108.  
  109.  mov edx,ecx
  110.  mov ecx,8
  111.  
  112. @Loop2:
  113.  rcl ah,1
  114.  rcr al,1
  115.  loop @Loop2
  116.  rcl ah,1
  117.  
  118.  mov ecx,edx
  119.  
  120.  mov [esi],al
  121.  mov [edi],ah
  122.  
  123.  inc esi
  124.  dec edi
  125.  loop @Loop
  126.  
  127. @End:
  128.  
  129.  pop edi
  130.  pop esi
  131. end;
  132.  
  133. procedure ShrByOneBit(var buffer;const Size:longword);
  134. asm
  135.  push edi
  136.  
  137.  mov edi,eax
  138.  mov ecx,edx
  139.  
  140.  jecxz @End
  141.  
  142.  dec ecx
  143.  jecxz @Rest
  144.  
  145. @Loop:
  146.  mov ax,[edi]
  147.  shr ax,1
  148.  stosb
  149.  loop @Loop
  150.  mov [edi],ah
  151.  jmp @End
  152.  
  153. @Rest:
  154.  shr byte ptr [edi],1
  155.  
  156. @End:
  157.  
  158.  pop edi
  159. end;
  160.  
  161. procedure ShrByEightBits(var Source,Dest;const Size:longword);
  162. asm
  163.  push esi
  164.  push edi
  165.  
  166.  lea esi,[eax+1]
  167.  mov edi,edx
  168.  
  169.  mov edx,ecx
  170.  or edx,edx
  171.  jz @End
  172.  
  173.  dec edx
  174.  
  175.  mov ecx,edx
  176.  jecxz @End
  177.  
  178.  shr ecx,2
  179.  rep movsd
  180.  
  181.  mov ecx,edx
  182.  and ecx,3
  183.  rep movsb
  184.  
  185.  mov [edi],cl
  186.  
  187. @End:
  188.  pop edi
  189.  pop esi
  190. end;
  191.  
  192. procedure XorBuffers(var Source,Dest;const Size:longword); overload;
  193. asm
  194.  push esi
  195.  push edi
  196.  
  197.  mov esi,eax
  198.  mov edi,edx
  199.  
  200.  mov edx,ecx
  201.  shr ecx,2
  202.  jecxz @Rest
  203.  
  204. @Loop:
  205.  mov eax,[esi]
  206.  xor [edi],eax
  207.  add esi,4
  208.  add edi,4
  209.  loop @Loop
  210.  
  211. @Rest:
  212.  mov ecx,edx
  213.  and ecx,3
  214.  jecxz @End
  215.  
  216. @Loop2:
  217.  mov al,[esi]
  218.  xor [edi],al
  219.  inc esi
  220.  inc edi
  221.  loop @Loop2
  222.  
  223. @End:
  224.  
  225.  pop edi
  226.  pop esi
  227. end;
  228.  
  229. procedure XorBuffers(const Source1,Source2;var Dest;const Size:longword); overload;
  230. asm
  231.  push esi
  232.  push edi
  233.  
  234.  mov esi,eax
  235.  mov edi,ecx
  236.  
  237.  mov ecx,Size
  238.  shr ecx,2
  239.  jecxz @Rest
  240.  
  241. @Loop:
  242.  mov eax,[esi]
  243.  xor eax,[edx]
  244.  mov [edi],eax
  245.  add esi,4
  246.  add edi,4
  247.  add edx,4
  248.  loop @Loop
  249.  
  250. @Rest:
  251.  mov ecx,Size
  252.  and ecx,3
  253.  jecxz @End
  254.  
  255. @Loop2:
  256.  mov al,[esi]
  257.  xor al,[edx]
  258.  mov [edi],al
  259.  inc esi
  260.  inc edi
  261.  inc edx
  262.  loop @Loop2
  263.  
  264. @End:
  265.  
  266.  pop edi
  267.  pop esi
  268. end;
  269.  
  270. procedure BuildTable(const SourcePolynom:TPolynom;var buffer;const ByteCount:cardinal);
  271. var i,j:integer;
  272.     Polynom:TEntry;
  273.     Value:TEntry;
  274.     ByteArray:PByteArray absolute buffer;
  275.     Offset:cardinal;
  276. begin
  277.  assert((ByteCount>=1) and (ByteCount<=32),'Invalid ByteCount');
  278.  move(SourcePolynom,Polynom,ByteCount);
  279.  ReverseBits(Polynom,ByteCount);
  280.  Offset:=0;
  281.  for i:=0 to 255 do
  282.  begin
  283.   fillchar(Value,ByteCount,0);
  284.   Value[0]:=i;
  285.   for j:=0 to 7 do if (value[0] and 1)<>0 then
  286.   begin
  287.    ShrByOneBit(Value,ByteCount);
  288.    XorBuffers(Polynom,Value,ByteCount);
  289.   end
  290.   else ShrByOneBit(Value,ByteCount);
  291.   move(Value,ByteArray[Offset],ByteCount);
  292.   inc(Offset,ByteCount);
  293.  end;
  294. end;
  295.  
  296. { TCRC }
  297.  
  298. constructor TCRC.Create(const APolynom: TPolynom;const AByteWidth: cardinal);
  299. begin
  300.  if (APolynom<>Polynom) or (AByteWidth<>ByteWidth) then
  301.  begin
  302.   setlength(FTable,AByteWidth*256);
  303.   BuildTable(APolynom,FTable,AByteWidth);
  304.   FPolynom:=APolynom;
  305.   FByteWidth:=AByteWidth;
  306.  end;
  307. end;
  308.  
  309. procedure TCRC.SetMasked(const AValue: boolean);
  310. begin
  311.  if AValue<>FMasked then FMasked:=AValue;
  312. end;
  313.  
  314. procedure TCRC.CalculateCRC(var Buffer; var Result;const BufferSize:integer);
  315. var i:integer;
  316.     ByteArray:TByteArray absolute Buffer;
  317.     ValueArray:TEntry;
  318.     TempArray:TEntry;
  319. begin
  320.  if FMasked then fillchar(ValueArray,ByteWidth,$ff) else fillchar(ValueArray,ByteWidth,0);
  321.  for i:=0 to BufferSize-1 do
  322.  begin
  323.   ShrByEightBits(ValueArray,TempArray,ByteWidth);
  324.   XorBuffers(TempArray,FTable[(ValueArray[0] xor ByteArray[i])*FByteWidth],ValueArray,ByteWidth);
  325.  end;
  326.  if Masked then
  327.  begin
  328.   fillchar(TempArray,ByteWidth,$ff);
  329.   XorBuffers(TempArray,ValueArray,ByteWidth);
  330.  end;
  331.  move(ValueArray,Result,ByteWidth);
  332. end;
  333.  
  334. { TCRC8 }
  335.  
  336. constructor TCRC8.Create;
  337. begin
  338.  inherited Create([0,1,3,4,7],1);
  339. end;
  340.  
  341. { TCRC16 }
  342.  
  343. constructor TCRC16.Create;
  344. begin
  345.  inherited Create([0,5,12],2);
  346. end;
  347.  
  348. { TCRC24 }
  349.  
  350. constructor TCRC24.Create;
  351. begin
  352.  inherited Create([0,1,5,6,23],3);
  353. end;
  354.  
  355. { TCRC32 }
  356.  
  357. constructor TCRC32.Create;
  358. begin
  359.  inherited Create([0,1,2,4,5,7,8,10,11,12,16,22,23,26],4);
  360. end;
  361.  
  362. { TCTC64 }
  363.  
  364. constructor TCTC64.Create;
  365. begin
  366.  inherited Create([0,1,4,7,9,10,12,13,17,19,21,22,23,24,27,29,31,32,33,35,37,38,39,40,45,46,47,52,53,54,55,57,62],8);
  367. end;
  368.  
  369. {
  370. CRC8=x8+x5+x4+x0
  371. CRC8=x8+x7+x4+x3+x1+x0
  372. CRC12=x12+x11+x3+x2+x1+x0
  373. CRC16=x16+x12+x5+x0
  374. CRC24=x24+x23+x6+x5+x1+x0
  375. CRC32=x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x1+x0
  376. CRC64=x64+x4+x3+x1+x0
  377. CRC64=x64+x62+x57+x55+x54+x53+x52+x47+x46+x45+x40+x39+x38+x37+x35+x33+x32+x31+x29+x27+x24+x23+x22+x21+x19+x17+x13+x12+x10+x9+x7+x4+x1+x0
  378. }
  379. end.
  380.