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)
转自:http://www.sanity-free.com/134/standard_crc_16_in_csharp.html