crc16 校验算法 C#
- 封装一个静态类
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TestApp { public class CRC { #region CRC16 public static byte[] CRC16(byte[] data) { int len = data.Length; if (len > 0) { ushort crc = 0xFFFF; for (int i = 0; i < len; i++) { crc = (ushort)(crc ^ (data[i])); for (int j = 0; j < 8; j++) { crc = (crc & 1) != 0 ? (ushort)((crc >> 1) ^ 0xA001) : (ushort)(crc >> 1); } } byte hi = (byte)((crc & 0xFF00) >> 8); //高位置 byte lo = (byte)(crc & 0x00FF); //低位置 return new byte[] { hi, lo }; } return new byte[] { 0, 0 }; } #endregion #region ToCRC16 public static string ToCRC16(string content) { return ToCRC16(content, Encoding.UTF8); } public static string ToCRC16(string content, bool isReverse) { return ToCRC16(content, Encoding.UTF8, isReverse); } public static string ToCRC16(string content, Encoding encoding) { return ByteToString(CRC16(encoding.GetBytes(content)), true); } public static string ToCRC16(string content, Encoding encoding, bool isReverse) { return ByteToString(CRC16(encoding.GetBytes(content)), isReverse); } public static string ToCRC16(byte[] data) { return ByteToString(CRC16(data), true); } public static string ToCRC16(byte[] data, bool isReverse) { return ByteToString(CRC16(data), isReverse); } #endregion #region ToModbusCRC16 public static string ToModbusCRC16(string s) { return ToModbusCRC16(s, true); } public static string ToModbusCRC16(string s, bool isReverse) { return ByteToString(CRC16(StringToHexByte(s)), isReverse); } public static string ToModbusCRC16(byte[] data) { return ToModbusCRC16(data, true); } public static string ToModbusCRC16(byte[] data, bool isReverse) { return ByteToString(CRC16(data), isReverse); } #endregion #region ByteToString public static string ByteToString(byte[] arr, bool isReverse) { try { byte hi = arr[0], lo = arr[1]; return Convert.ToString(isReverse ? hi + lo * 0x100 : hi * 0x100 + lo, 16).ToUpper().PadLeft(4, '0'); } catch (Exception ex) { throw (ex); } } public static string ByteToString(byte[] arr) { try { return ByteToString(arr, true); } catch (Exception ex) { throw (ex); } } #endregion #region StringToHexString public static string StringToHexString(string str) { StringBuilder s = new StringBuilder(); foreach (short c in str.ToCharArray()) { s.Append(c.ToString("X4")); } return s.ToString(); } #endregion #region StringToHexByte private static string ConvertChinese(string str) { StringBuilder s = new StringBuilder(); foreach (short c in str.ToCharArray()) { if (c <= 0 || c >= 127) { s.Append(c.ToString("X4")); } else { s.Append((char)c); } } return s.ToString(); } private static string FilterChinese(string str) { StringBuilder s = new StringBuilder(); foreach (short c in str.ToCharArray()) { if (c > 0 && c < 127) { s.Append((char)c); } } return s.ToString(); } /// <summary> /// 字符串转16进制字符数组 /// </summary> /// <param name="hex"></param> /// <returns></returns> public static byte[] StringToHexByte(string str) { return StringToHexByte(str, false); } /// <summary> /// 字符串转16进制字符数组 /// </summary> /// <param name="str"></param> /// <param name="isFilterChinese">是否过滤掉中文字符</param> /// <returns></returns> public static byte[] StringToHexByte(string str, bool isFilterChinese) { string hex = isFilterChinese ? FilterChinese(str) : ConvertChinese(str); //清除所有空格 hex = hex.Replace(" ", ""); //若字符个数为奇数,补一个0 hex += hex.Length % 2 != 0 ? "0" : ""; byte[] result = new byte[hex.Length / 2]; for (int i = 0, c = result.Length; i < c; i++) { result[i] = Convert.ToByte(hex.Substring(i * 2, 2), 16); } return result; } #endregion } }
- 调用测试
static void Main(string[] args) { string msg = "01 2C 00 00 00 00 00 00 0A 4F 4F 05 93 00 07 06 15 00 00 00 23 3D F5 7C 45 71 20 00 45 71 20 00 00 00 00 00 40 DF 70 E3 00 00 00 00 BF 8F D6 63 00 00 00 00 00 00 00 00 10 20 00 00 41 30 00 00 23 3D F9 00 45 71 20 00 45 71 20 00 00 00 00 00 00 00 00 00 00 00 00 00 BF 8E 47 99 00 00 00 00 00 00 00 00 10 20 00 00 41 30 00 00 23 3D FC 84 45 71 20 00 45 71 20 00 00 00 00 00 00 00 00 00 00 00 00 00 BF 8A FD 76 00 00 00 00 00 00 00 00 10 20 00 00 41 30 00 00 23 3E 00 08 45 71 20 00 45 71 20 00 00 00 00 00 00 00 00 00 00 00 00 00 BF 92 C7 B9 00 00 00 00 00 00 00 00 10 20 00 00 41 30 00 00 23 3E 03 8C 45 71 20 00 45 71 20 00 00 00 00 00 00 00 00 00 00 00 00 00 BF 8A A4 FD 00 00 00 00 00 00 00 00 10 20 00 00 41 30 00 00 23 3E 07 10 45 71 20 00 45 71 20 00 00 00 00 00 00 00 00 00 00 00 00 00 BF 8D EE CC 00 00 00 00 00 00 00 00 10 20 00 00 41 30 00 00 23 3E 0A 94 45 71 20 00 45 71 20 00 00 00 00 00 00 00 00 00 00 00 00 00 BF 88 38 B0 00 00 00 00 00 00 00 00 10 20 00 00 41 30 00 00 23 3E 0E 18 45 71 40 00 45 71 50 00 00 00 00 00 41 1F D4 4B 00 00 00 00 BF 7C 04 97 00 00 00 00 00 00 00 00 10 20 00 00 41 30 00 00 23 3E 11 9C 45 71 70 00 45 71 70 00 00 00 00 00 41 15 7B 74 00 00 00 00 BF 8E A0 12 00 00 00 00 00 00 00 00 10 20 00 00 41 30 00 00 23 3E 15 20 45 71 90 00 45 71 90 00 00 00 00 00 40 E1 D9 FE 00 00 00 00 BF 8C E5 0D 00 00 00 00 00 00 00 00 10 20 00 00 41 30 00 00"; var a = CRC.ToCRC16(msg, true); //结果为: var b = CRC.ToCRC16(msg, false); //结果为: var c = CRC.ToModbusCRC16(msg, true); //结果为: var e = CRC.ToModbusCRC16(msg, false); var d = CRC.ToCRC16("你好,我们测试一下CRC16算法", true); //结果为: }
完成。