pythondelphicrc32

Problem in converting a Python code to Delphi


I need to convert a Python code to Delphi but I cant.

The Python code is:

def crc32(data: bytes, initial):
crc = initial
for x in data:
    for k in range(8):
        if ((crc ^ x) & 0x01) == 1:
            crc = crc >> 1
            crc = crc ^ 0x04c11db7
        else:
            crc = crc >> 1
        x = x >> 1
crc &= 0xffffffff
return crc

but when I translate to Delphi code I have a problem, the problem is the line x = x >> 1

this is the Delphi code:

function TForm1.CalculateCRC32(const data: TBytes; initial: Cardinal): Cardinal;
var
  crc: Cardinal;
  x, z: Integer;
begin
 crc := initial;

 for x in data do
 begin
    for z := 0 to 7 do
    begin
      if ((crc xor x) and $01) = 1 then
      begin
        crc := crc shr 1;
        crc := crc xor $04c11db7;
      end
      else
      begin
       crc := crc shr 1;
      end;

      x := x shr 1; // here its the problem I have
    end;
 end;
 crc := crc and $ffffffff;
 Result := crc;
end;

How could I solve this problem? Thanks in advance.

I am using Delphi XE11.3

to make a test, I do:

data := '123456780000000077000000';
bytedata := HexToBytes(data); //TBytes type

initDataStr := '$FFFFFFFF'; 
initData := Cardinal(StrToInt64(initDataStr));

result := CalculateCRC32(bytedata, initData); //The result should be 7085D2 in hexadecimal. 

Solution

  • You can try this way.

    But you have same basic error in Delphi and Python loop and syntax.

    function TForm1.CalculateCRC32(const data: TBytes; initial: Cardinal): Cardinal;
    var
      crc, x: Cardinal;
      i, z: Integer;
    begin
      crc := initial;
    
      for i := 0 to High(data) do
      begin
        x := data[i];
        for z := 0 to 7 do
        begin
          if ((crc xor x) and $01) = 1 then
          begin
            crc := crc shr 1;
            crc := crc xor $04c11db7;
          end
          else
          begin
            crc := crc shr 1;
          end;
    
          x := x shr 1;
        end;
      end;
    
      crc := crc and $ffffffff;
      Result := crc;
    end;
    

    I just avoid changing the loop variable x by using the z variable to regulate the bit-wise operations, ensuring the loop functions as intended.