views:

594

answers:

2

I am working on a function that will give me a Kermit CRC value from a HEX string. I have a piece of code in DELPHI. I am a .NET developer and need the code in C#.

function CRC_16(cadena : string):word; 
var 
valuehex : word; 
i: integer; 
CRC : word; 
Begin 
   CRC := 0; 
   for i := 1 to length(cadena) do 
   begin 
      valuehex := ((ord(cadena[i]) XOR CRC) AND $0F) * $1081; 
      CRC := CRC SHR 4; 
      CRC := CRC XOR valuehex; 
      valuehex := (((ord(cadena[i]) SHR 4) XOR LO(CRC)) AND $0F); 
      CRC := CRC SHR 4; 
      CRC := CRC XOR (valuehex * $1081); 
   end; 
  CRC_16 := (LO(CRC) SHL 8) OR HI(CRC); 
end;

I got the code from this webpage: Kermit CRC in DELPHI

I guess that Delphi function is correct. If any one can please convert the code to C# that will be great. I tried to convert to C#, but got lost in WORD data type and the LO function of Delphi. Thank you all.

+1  A: 

From MSDN forums:

static long ComputeCRC(byte[] val)
{
    long crc;
    long q;
    byte c;
    crc = 0;
    for (int i = 0; i < val.Length; i++)
    {
        c = val[i];
        q = (crc ^ c) & 0x0f;
        crc = (crc >> 4) ^ (q * 0x1081);
        q = (crc ^ (c >> 4)) & 0xf;
        crc = (crc >> 4) ^ (q * 0x1081);
    }
    return (byte)crc << 8 | (byte)(crc >> 8);
}

Use Encoding.ASCII.GetBytes(string) to convert a string to a byte[].

dtb
YES! It worked 95% correctly. This is the URL I am using as reference:- http://www.lammertbies.nl/comm/info/crc-calculation.htmlfor a HEX string 'absdef' that URL gives (KERMIT) = 0x5A43, but the above code gives = 435A. So the first and last two LETTERS/DIGITS are swapped. All I did now is = String result = crc.ToString("X"); result = result.Substring(2, 2) + result.Substring(0, 2);I need the result in String, so it works fine now.Thanks. I will accept this answer, even if you do not post to fixed swapped 2-letter issue. Not a big deal, it worked, I am happy.
Mehdi Anis
@dtb: SERIOUS Problem: for HexString = ACA1F0FE00000000, the Kermit CRC = 8602. The above code gives = 286. Now I cannot translate 286 to 8602 using my above comment's method.
Mehdi Anis
@Mehdi Anis: I've updated my answer to swap the bytes. It now returns 0x8602 for your hex string.
dtb
@dtb: Much appreciated
Mehdi Anis
A: 

A word is a 16-bit unsigned integer (which can store the values 0..65535).

Lo returns the low-order byte of an integer. So if the integer is 0x7B41AF, for example, lo will return 0xAF.

Andreas Rejbrand
I know those. I don't know: What is WORD's equivalent data type in C#? I am also looking for an equivalent LO function in C#.
Mehdi Anis
OK. I do not know C#, but - as dtb replied above - it is trivial to implement the "lo" function. Indeed, to obtain the low-order byte of X, simply AND it with 0xFF.
Andreas Rejbrand
UInt16 or "unsigned short"
alex