using System.ComponentModel.DataAnnotations; using JiShe.CollectBus.Common.Enums; using JiShe.CollectBus.Common.Models; namespace JiShe.CollectBus.Common.Extensions { public static class HexStringExtensions { //起始字符 private const string startStr = "68"; //结束字符 private const string endStr = "16"; //头部字节长度 private const int hearderLen = 6; //消息认证码字段长度 private const int pWLen = 16; private const int FixedLength = 18; public static object GetAnalyzeValue(this List hexStringList, CommandChunkEnum chunk) { if (hexStringList.Count < hearderLen || hexStringList[0] != startStr || hexStringList[5] != startStr || hexStringList.Count < FixedLength) { return null; } switch (chunk) { case CommandChunkEnum.AFN: var aFn = hexStringList[(int)CommandChunkEnum.AFN].HexToDec();//1字节 return aFn; case CommandChunkEnum.FN: //(DT2*8)+DT1=fn var dt1Bin = hexStringList[(int)CommandChunkEnum.FN - 1].HexToBin(); var dt1 = dt1Bin != "0" ? dt1Bin.Length : 0; var dt2 = hexStringList[(int)CommandChunkEnum.FN].HexToDec(); var fn = dt2 * 8 + dt1; return fn; case CommandChunkEnum.A: var aHexList = hexStringList.Skip((int)CommandChunkEnum.A).Take(5).ToList(); var a1 = aHexList[1] + aHexList[0]; var a2 = aHexList[3] + aHexList[2]; var a2Dec = a2.HexToDec(); var a3 = aHexList[4]; var a = $"{a1}{a2Dec.ToString().PadLeft(5, '0')}"; var a3Bin = aHexList[4].HexToBin().PadLeft(8, '0'); var msa = a3Bin.Substring(0, 7).BinToDec(); return new Tuple(a, msa); case CommandChunkEnum.SEQ: var seq = hexStringList[(int)CommandChunkEnum.SEQ].HexToBin().PadLeft(8, '0'); var tpV = (TpV)Convert.ToInt32(seq.Substring(0, 1)); var firfin = (FIRFIN)Convert.ToInt32(seq.Substring(1, 2)); var con = (CON)Convert.ToInt32(seq.Substring(3, 1)); var prseqBin = seq.Substring(4, 4); return new Seq { CON = con, FIRFIN = firfin, PRSEQ = prseqBin.BinToDec(), TpV = tpV }; case CommandChunkEnum.Data: var lenIndex = (int)CommandChunkEnum.Len; var lenBin = (hexStringList[lenIndex + 1]+hexStringList[lenIndex]).HexToBin(); var len = lenBin.Remove(lenBin.Length - 2).BinToDec(); //验证长度 2=(帧校验和+结束字符) if (hexStringList.Count - 2 != hearderLen + len) return null; var dataHexList = hexStringList.Skip(FixedLength).Take(len + hearderLen - FixedLength).ToList(); return dataHexList; default: throw new ArgumentOutOfRangeException(nameof(chunk), chunk, null); } } public static bool IsStartStr(this string str) { return str == startStr ? true : false; } /// /// 字节加33 /// /// /// public static List AddHex33(this List hexStringList) { for (int i = 0; i < hexStringList.Count; i++) { hexStringList[i] = (Convert.ToInt32(hexStringList[i], 16) + Convert.ToInt32("33", 16)).ToString("X2"); if (hexStringList[i].Length > 2) { hexStringList[i] = hexStringList[i].Substring(hexStringList[i].Length - 2); } } return hexStringList; } /// /// 字节减33 /// /// /// 是否反转 /// public static List ReduceHex33(this List hexStringList,bool isReverse = false) { for (int i = 0; i < hexStringList.Count; i++) { var value = Convert.ToInt32(hexStringList[i], 16) - Convert.ToInt32("33", 16); hexStringList[i] = value.DecToHex().PadLeft(2, '0'); } if(isReverse) hexStringList.Reverse(); return hexStringList; } public static string GetCRC(List inputFrm, int startIndex = 0) { int sum = 0; for (int i = startIndex; i < inputFrm.Count; i++) { sum += (Convert.ToInt32(inputFrm[i], 16)); } var sum16 = Convert.ToString(sum, 16); return sum16.Substring(sum16.Length - 2, 2).ToUpper(); } public static byte[] GetCRC16(byte[] data, bool isReverse = false) { int len = data.Length; if (data == null || data.Length == 0) return new byte[] { 0, 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); //低位置 if (isReverse) return new byte[] { lo, hi }; return new byte[] { hi, lo }; } } }