Help converting Delphi function to GO [SOLVED]

Hey there, I got a Delphi function which gives me a CRC calc from a package sent by a GPS tracker, could anyone help me rewriting this function in GO?



function Crc16(strDeger:String):Cardinal;
  const
    bMask : array[0..31] of DWord =
      ($00000001, $00000002, $00000004, $00000008,
       $00000010, $00000020, $00000040, $00000080,
       $00000100, $00000200, $00000400, $00000800,
       $00001000, $00002000, $00004000, $00008000,
       $00010000, $00020000, $00040000, $00080000,
       $00100000, $00200000, $00400000, $00800000,
       $01000000, $02000000, $04000000, $08000000,
       $10000000, $20000000, $40000000, $80000000);
  function CrcReflect(dwDeger: DWord; BitSay:Word ): DWord;
  var
    i   : Integer;
  begin
    Result := dwDeger;
    for i := 0 to (BitSay-1) do
    begin
      if (dwDeger and 1) <> 0
      then Result := Result or      bMask[(BitSay-1) - i]
      else Result := Result and not bMask[(BitSay-1) - i];
      dwDeger := dwDeger shr 1;
    end;
  end;
var
  i,j: Integer;
  Data   : DWord;
begin
  Result := $FFFF;
  for i  := 1 to Length(strDeger) do
  begin
    Data   := CrcReflect( Ord(strDeger[i] ), 8 );
    Result := Result xor ( Data shl 8 );
    for j := 0 to 7 do
    begin
      if (Result and $8000 ) <> 0
        then Result:=(Result shl 1) xor $1021
        else Result:= Result shl 1;
      Result := Result and $FFFF;
    end;
  end;
  Result:= CrcReflect( Result, 16 ) xor $FFFF;
end;

Appreciate any kind of help.

https://play.golang.org/p/1c_HZ2vPbj

Add randomized tests to fully flush out any possible mistakes. I did not cross-validate, so there might be small bugs lurking somewhere.

2 Likes

That works perfectlyh my friend! Thank you.

1 Like

It’s a lot simpler if you skip reversing the order of the bits. (I also swapped the zeroes and ones, but that isn’t as significant.) I suspect the original function was derived from one in a version of Pascal that didn’t have bit shift operators, so it was cheaper to shift left (by multiplying by two) than to shift right (by dividing by two).

func CRC16(data []byte) uint16 {
	crc := uint16(0)
	for _, b := range data {
		crc = crc ^ uint16(b)
		for k := 0; k < 8; k++ {
			if crc&1 == 0 {
				crc = (crc >> 1) ^ 0x0408
			} else {
				crc = (crc >> 1) | 0x8000
			}
		}
	}

	return crc
}
2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.