Question

I am very new to Ruby, please help.

This is a C code which I need to convert into Ruby.

Passing values [1,2,3,4,5] it gives me B059 in HEX

    unsigned short CalcCrc16(const unsigned char *Data,unsigned short DataLen)
    {
      unsigned short Temp;
      unsigned short Crc;
      Crc = 0;
      while (DataLen--)
      {
             Temp = (unsigned short)((*Data++) ^ (Crc >> 8));
             Temp ^= (Temp >> 4);
             Temp ^= (Temp >> 2);
             Temp ^= (Temp >> 1);
             Crc = (Crc << 8) ^ (Temp << 15) ^ (Temp << 2) ^ Temp;
      }
        return Crc; 
   }

This is the Ruby code I have tried:

class CRC16 
  def CRC16.CalculateCrc16(data) 
    crc = 0x0000 
    temp = 0x0000 
    i = 0 
    while i < data.Length 
      value = data[i] 
      temp = (value ^ (crc >> 8)) 
      temp = (temp ^ (temp >> 4)) 
      temp = (temp ^ (temp >> 2)) 
      temp = (temp ^ (temp >> 1)) 
      crc = (((crc << 8) ^ (temp << 15) ^ (temp << 2) ^ temp)) 
      i += 1 
    end 
    return crc 
  end 
end

Please help me to convert this code into Ruby. Thanks Deepak

Was it helpful?

Solution

You are almost there.

Here is the fix:

class CRC16 
  def CRC16.CalculateCrc16(data) 
    crc = 0
    temp = 0
    i = 0 
    while i < data.length    # Modified from OP version
      value = data[i] 
      temp = (value ^ (crc >> 8)) 
      temp = (temp ^ (temp >> 4)) 
      temp = (temp ^ (temp >> 2)) 
      temp = (temp ^ (temp >> 1)) 
      crc = (((crc << 8) ^ (temp << 15) ^ (temp << 2) ^ temp))
      crc &= 0xffff          # New - keep integer in "unsigned short" bit space
      i += 1 
    end 
    return crc 
  end 
end

I changed just two things to make it work as per the C version:

  • Length -> length, a typo
  • Ruby doesn't do short, or any other kind of restriction on integer size. You have to add it. That is what crc &= 0xffff is doing. Without it, bits shifted "out" of the short come back to haunt you and give a nonsense result.

In addition, I replaced 0x0000 with 0, as it looked like an attempt to get Ruby to treat the integers as "short", which is not possible this way.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top