Comment générer un CRC-16 à partir de C #

J’essaie de générer un CRC-16 en utilisant C #. Le matériel que j’utilise pour RS232 nécessite que la chaîne d’entrée soit HEX. La capture d’écran ci-dessous montre la conversion correcte. Pour un test, il faut que 8000 soit 0xC061, mais la méthode C # qui génère CRC-16 doit pouvoir convertir n’importe quelle chaîne HEX donnée.

Capture d'écran de la sortie requise.

J’ai essayé d’utiliser Nito.KitchenSink.CRC

J’ai également essayé le ci-dessous qui génère 8009 lorsque 8000 est entré –

public ssortingng CalcCRC16(ssortingng strInput) { ushort crc = 0x0000; byte[] data = GetBytesFromHexSsortingng(strInput); for (int i = 0; i < data.Length; i++) { crc ^= (ushort)(data[i] << 8); for (int j = 0; j  0) crc = (ushort)((crc << 1) ^ 0x8005); else crc <<= 1; } } return crc.ToString("X4"); } public Byte[] GetBytesFromHexString(string strInput) { Byte[] bytArOutput = new Byte[] { }; if (!string.IsNullOrEmpty(strInput) && strInput.Length % 2 == 0) { SoapHexBinary hexBinary = null; try { hexBinary = SoapHexBinary.Parse(strInput); if (hexBinary != null) { bytArOutput = hexBinary.Value; } } catch (Exception ex) { MessageBox.Show(ex.Message); } } return bytArOutput; } 

Et c’est parti; notez qu’il s’agit d’une version spécifique de la CRC-16 – il est déroutant de dire simplement “CRC-16”. Ceci emprunte quelques détails d’implémentation à l’ adresse http://www.sanity-free.com/ – remarque: je l’ai rendu static lieu d’instance.

 using System; static class Program { static void Main() { ssortingng input = "8000"; var bytes = HexToBytes(input); ssortingng hex = Crc16.ComputeChecksum(bytes).ToSsortingng("x2"); Console.WriteLine(hex); //c061 } static byte[] HexToBytes(ssortingng input) { byte[] result = new byte[input.Length / 2]; for(int i = 0; i < result.Length; i++) { result[i] = Convert.ToByte(input.Substring(2 * i, 2), 16); } return result; } public static class Crc16 { const ushort polynomial = 0xA001; static readonly ushort[] table = new ushort[256]; public static 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; } static 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; } } } } 

En plus, si vous voulez CRC16-CCITT.

  private ushort Crc16Ccitt(byte[] bytes) { const ushort poly = 4129; ushort[] table = new ushort[256]; ushort initialValue = 0xffff; ushort temp, a; ushort crc = initialValue; for (int i = 0; i < table.Length; ++i) { temp = 0; a = (ushort)(i << 8); for (int j = 0; j < 8; ++j) { if (((temp ^ a) & 0x8000) != 0) temp = (ushort)((temp << 1) ^ poly); else temp <<= 1; a <<= 1; } table[i] = temp; } for (int i = 0; i < bytes.Length; ++i) { crc = (ushort)((crc << 8) ^ table[((crc >> 8) ^ (0xff & bytes[i]))]); } return crc; }