using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BatCharging.Service { public class BitsConvertUtils { public static byte GetByte(byte[] data, int bitSize, int bitOffset) { int byteOffset = bitOffset / 8; var b = data[byteOffset]; var offset = bitOffset % 8; b >>= offset; byte mask = (byte)(2 ^ bitSize - 1); b &= mask; return b; } public static int GetInt(byte[] data, int bitSize, int bitOffset) { int rightShift = 32 - bitSize; int byteOffset = bitOffset / 8; byte b1 = data[byteOffset]; byte b2 = data[byteOffset + 1]; byte b3 = data[byteOffset + 2]; byte b4 = data[byteOffset + 3]; var barray = new BitArray(new byte[] { b4, b3, b2, b1 }); int i = 0; for (int d = rightShift; d < rightShift + bitSize; d++) { if (barray[d]) i += Convert.ToInt32(Math.Pow(2, d - rightShift)); } return i; } public static byte[] GetByteArray(byte[] data, int bitSize, int bitOffset) { var bytes = bitSize / 8; var byteOffset = bitOffset / 8; var dest = new byte[bytes]; Array.Copy(data, byteOffset, dest, 0, bytes); return dest; } private String ToFullBinaryStr(byte num) { char[] rst = new char[8]; for (int i = 0; i < 8; i++) { rst[8 - 1 - i] = (char)((num >> i & 1) + '0'); } return new String(rst); } /// /// 将一个字节转换到二进制字节数组.(高位在位数组低索引位,低位在位数组高索引位) /// /// 需转换字节 /// 二进制字节数组 private static byte[] ToFullBinaryBytes(byte num) { byte[] rst = new byte[8]; for (int i = 0; i < 8; i++) { rst[i] = (byte)((num >> i & 1)); } return rst; } /// /// 得到字节中单Bit的值(高字节在数组低索引位,低字节在数组高索引位) /// /// 字节数组 /// 字节位置:数组中第几个字节(从0开始) /// Bit在字节中的位置:第几位(从0开始) /// 返回字节结果,byte:1,0 public static byte ByteToBitValue(byte[] data, int byteAddr, int bitStartAddr) { byte result = 9; if (data.Count() >= (byteAddr + 1)) { byte value = data[byteAddr]; result = ToFullBinaryBytes(value)[bitStartAddr]; } return result; } /// /// 得到字节中Bit组合的值,高位在前,低位在后(高字节在数组低索引位,低字节在数组高索引位) /// /// 字节数组 /// 字节位置:数组中第几个字节(从0开始) /// Bit在字节中的位置:第几位(从0开始) /// 字节中位的偏移量 /// 返回字节结果,byte:1,0 public static byte ByteToBitsValue(byte[] data, int byteAddr, int bitStartAddr, int bitOffset) { //msg.CSCT01 = (byte)(BitsConvertUtils.ByteToBitsValue(data, 3, 0, 8)-50); byte result = 9; if (data.Count() >= (byteAddr + 1)) { byte value = data[byteAddr]; if ((bitStartAddr + bitOffset) <= 8) { byte temp = 0; for (int i = bitStartAddr; i < bitStartAddr + bitOffset; i++) { temp += (byte)(((value >> i & 1)) << (i - bitStartAddr)); } result = temp; } } return result; } /// /// 根据高位优先的原理的两字节数据解析返回一个16位无符号整数(高字节在数组低索引位,低字节在数组高索引位) /// /// 原字节数组 /// 缓冲区偏移 /// 返回无符号整数 public static ushort ToUInt16(byte[] value, int offset) { return (ushort)((value[offset] << 8) + value[offset + 1]); } /// /// 根据高位优先的原理的两字节数据解析返回一个16位无符号整数 /// /// 高字节 /// 低字节 /// public static ushort ToUInt16(byte valH, byte valL) { return (ushort)((valH << 8) + valL); } public static void WriteBit(ref byte[] data, int bitoffset, int bitSize, int value) { int byteoffset = bitoffset / 8; int offset = bitoffset % 8; value = value << bitoffset; var d = data[byteoffset]; d = (byte)((int)d & value); data[byteoffset] = d; } public static void WriteBit(ref byte[] data, int bitoffset, int bitSize, byte[] value) { int byteoffset = bitoffset / 8; for (int i = byteoffset; i < value.Length; i++) { data[i] = value[i - byteoffset]; } } /// /// 将字符串转换成字节数组 /// /// 字符串 /// 字节数组 public static byte[] StrToBytes(string StrSrc) { byte[] byteResults = null; List lstBytes = null; if (StrSrc != null) { if (StrSrc.Trim() != "") { lstBytes = new List(); int iLength = StrSrc.Length / 2; for (int i = 0; i < iLength; i++) { string strElet = StrSrc.Substring(i * 2, 2); byte element = Convert.ToByte(strElet, 16); ; lstBytes.Add((byte)element); } byteResults = lstBytes.ToArray(); } } return byteResults; } /// /// 将字符串转换成高低位转换的字节数组-目前此方法只解决0x00两个字符组成一个字节的情形,如果是单字符解决不了 /// /// 字符串 /// 高低位转换的字节数组 public static byte[] StrToRevBytes(string StrSrc) { byte[] byteResults = null; List lstBytes = null; if (StrSrc != null) { if (StrSrc.Trim() != "") { lstBytes = new List(); int iLength = StrSrc.Length / 2; for (int i = 0; i < iLength; i++) { string strElet = StrSrc.Substring(i * 2, 2); byte element = Convert.ToByte(strElet, 16); ; lstBytes.Add((byte)element); } if (lstBytes != null) { List lstTemp = new List(); if (lstBytes.Count > 0) { int num = lstBytes.Count; for (int j = 0; j < num; j++) { lstTemp.Add(lstBytes[num - 1 - j]); } } byteResults = lstTemp.ToArray(); } } } return byteResults; } /// /// 字节数组转16进制字符串:空格分隔 /// /// /// public static string BytesToHexStr(byte[] byteDatas) { StringBuilder builder = new StringBuilder(); for (int i = 0; i < byteDatas.Length; i++) { builder.Append(string.Format("{0:X2} ", byteDatas[i])); } return builder.ToString().Trim(); } /// /// 16进制格式字符串转字节数组 /// /// /// public static byte[] HexStrToBytes(string hexStr) { //以 ' ' 分割字符串,并去掉空字符 string[] chars = hexStr.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); byte[] returnBytes = new byte[chars.Length]; //逐个字符变为16进制字节数据 for (int i = 0; i < chars.Length; i++) { returnBytes[i] = Convert.ToByte(chars[i], 16); } return returnBytes; } /// /// 32进制数高低位对调 /// /// /// 字节数组 public static byte[] UInt32ToBytes(UInt32 value) { byte[] bytesResult = new byte[4]; byte[] temp = new byte[4]; BitConverter.GetBytes(Convert.ToUInt32(value)).CopyTo(temp, 0); bytesResult[0] = temp[3]; bytesResult[1] = temp[2]; bytesResult[2] = temp[1]; bytesResult[3] = temp[0]; return bytesResult; } } }