tags:

views:

874

answers:

1

How to calculate CRC_B encoding in C# as described in ISO 14443? Here is some background info:

CRC_B encoding This annex is provided for explanatory purposes and indicates the bit patterns that will exist in the physical layer. It is included for the purpose of checking an ISO/IEC 14443-3 Type B implementation of CRC_B encoding. Refer to ISO/IEC 3309 and CCITT X.25 2.2.7 and V.42 8.1.1.6.1 for further details. Initial Value = 'FFFF'

  • Example 1: for 0x00 0x00 0x00 you should end up with CRC_B of 0xCC 0xC6
  • Example 2: for 0x0F 0xAA 0xFF you should end up with CRC_B of 0xFC 0xD1

I tried some random CRC16 libraries but they aren't giving me the same results. I didn't get the same results from online checks either like in here.

+1  A: 

I reversed this from the C code in ISO/IEC JTC1/SC17 N 3497 so its not pretty but does what you need:

public class CrcB
{
    const ushort __crcBDefault = 0xffff;

    private static ushort UpdateCrc(byte b, ushort crc)
    {
            unchecked
            {
                byte ch = (byte)(b^(byte)(crc & 0x00ff));
                ch = (byte)(ch ^ (ch << 4));
                return (ushort)((crc >> 8)^(ch << 8)^(ch << 3)^(ch >> 4));
            }
    }

    public static ushort ComputeCrc(byte[] bytes)
    {
            var res = __crcBDefault;
            foreach (var b in bytes)
                    res = UpdateCrc(b, res);
            return (ushort)~res;
    }
}

As a test, try the code below:

 public static void Main(string[] args) 
 {
     // test case 1 0xFC, 0xD1
     var bytes = new byte[] { 0x0F, 0xAA, 0xFF };
     var crc = CrcB.ComputeCrc(bytes);
     var cbytes = BitConverter.GetBytes(crc);

     Console.WriteLine("First (0xFC): {0:X}\tSecond (0xD1): {1:X}", cbytes[0], cbytes[1]);

     // test case 2 0xCC, 0xC6
     bytes = new byte[] { 0x00, 0x00, 0x00 };
     crc = CrcB.ComputeCrc(bytes);
     cbytes = BitConverter.GetBytes(crc);
     Console.WriteLine("First (0xCC): {0:X}\tSecond (0xC6): {1:X}", cbytes[0], cbytes[1]);


     Console.ReadLine();
}
cfeduke
I'm getting following exception when I try to run this test: System.OverflowException: Arithmetic operation resulted in an overflow.It points to line: ch = (byte)(ch ^ (ch << 4));
Tommi L.
What byte values are you using that's creating the exception? I've tried a ton of variations but I cannot get an overflow. It may be that overflowing is necessary, I'm not familiar enough with C compilers to know if that is the default. I have modified the code to reflect this.
cfeduke
That was the case. I had to uncheck the "Check for arithmetic overflow/underflow" option from the project properties to make this work with SharpDevelop IDE.
Tommi L.