§ December 15, 2006

Standard CRC 16 in C#

I've been working on a service at work that will end up being this big cluster of servers that all talk with each other.  One of the things I needed was a small crc checksum for some of the more compact UDP messages that get sent around.  I thought about just using the CRC16-CCITT library I already had, but decided on using the standard CRC16 algorithm.  Since I posted the CRC32 and CRC16-CCITT implementations I thought I'd post this one too.

using System;

public class Crc16 {
    const ushort polynomial = 0xA001;
    ushort[] table = new ushort[256];

    public ushort ComputeChecksum(byte[] bytes) {
        ushort crc = 0;
        for(int i = 0; i < bytes.Length; ++i) {
            byte index = (byte)(crc ^ bytes[i]);
            crc = (ushort)((crc >> 8) ^ table[index]);
        }
        return crc;
    }

    public byte[] ComputeChecksumBytes(byte[] bytes) {
        ushort crc = ComputeChecksum(bytes);
        return BitConverter.GetBytes(crc);
    }

    public Crc16() {
        ushort value;
        ushort temp;
        for(ushort i = 0; i < table.Length; ++i) {
            value = 0;
            temp = i;
            for(byte j = 0; j < 8; ++j) {
                if(((value ^ temp) & 0x0001) != 0) {
                    value = (ushort)((value >> 1) ^ polynomial);
                }else {
                    value >>= 1;
                }
                temp >>= 1;
            }
            table[i] = value;
        }
    }
}
If you need for this code to be CLS compliant, you can change the method signature's return type from ushort to int and it will operate the same (the ushort crc value will be implicitly converted from ushort to int)

Links to the other C# CRC implementations CRC16-CCITT, CRC16-CCITT Kermit, CRC32, and CRC8
Posted 11 years, 4 months ago on December 15, 2006

 Comments can be posted in the forums.

© 2003 - 2017 NullFX
Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License