158 lines
6.0 KiB
C#
158 lines
6.0 KiB
C#
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<string> 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<string,int>(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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 字节加33
|
|
/// </summary>
|
|
/// <param name="hexStringList"></param>
|
|
/// <returns></returns>
|
|
public static List<string> AddHex33(this List<string> 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 字节减33
|
|
/// </summary>
|
|
/// <param name="hexStringList"></param>
|
|
/// <param name="isReverse">是否反转</param>
|
|
/// <returns></returns>
|
|
public static List<string> ReduceHex33(this List<string> 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<string> 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 };
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|