You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

297 lines
10 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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);
}
/// <summary>
/// 将一个字节转换到二进制字节数组.(高位在位数组低索引位,低位在位数组高索引位)
/// </summary>
/// <param name="num">需转换字节</param>
/// <returns>二进制字节数组</returns>
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;
}
/// <summary>
/// 得到字节中单Bit的值(高字节在数组低索引位,低字节在数组高索引位)
/// </summary>
/// <param name="data">字节数组</param>
/// <param name="byteAddr">字节位置:数组中第几个字节(从0开始)</param>
/// <param name="bitStartAddr">Bit在字节中的位置:第几位(从0开始)</param>
/// <returns>返回字节结果byte:1,0</returns>
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;
}
/// <summary>
/// 得到字节中Bit组合的值,高位在前,低位在后(高字节在数组低索引位,低字节在数组高索引位)
/// </summary>
/// <param name="data">字节数组</param>
/// <param name="byteAddr">字节位置:数组中第几个字节(从0开始)</param>
/// <param name="bitStartAddr">Bit在字节中的位置:第几位(从0开始)</param>
/// <param name="bitOffset">字节中位的偏移量</param>
/// <returns>返回字节结果byte:1,0</returns>
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;
}
/// <summary>
/// 根据高位优先的原理的两字节数据解析返回一个16位无符号整数(高字节在数组低索引位,低字节在数组高索引位)
/// </summary>
/// <param name="value">原字节数组</param>
/// <param name="offset">缓冲区偏移</param>
/// <returns>返回无符号整数</returns>
public static ushort ToUInt16(byte[] value, int offset)
{
return (ushort)((value[offset] << 8) + value[offset + 1]);
}
/// <summary>
/// 根据高位优先的原理的两字节数据解析返回一个16位无符号整数
/// </summary>
/// <param name="valH">高字节</param>
/// <param name="valL">低字节</param>
/// <returns></returns>
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];
}
}
/// <summary>
/// 将字符串转换成字节数组
/// </summary>
/// <param name="StrSrc">字符串</param>
/// <returns>字节数组</returns>
public static byte[] StrToBytes(string StrSrc)
{
byte[] byteResults = null;
List<byte> lstBytes = null;
if (StrSrc != null)
{
if (StrSrc.Trim() != "")
{
lstBytes = new List<byte>();
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;
}
/// <summary>
/// 将字符串转换成高低位转换的字节数组-目前此方法只解决0x00两个字符组成一个字节的情形如果是单字符解决不了
/// </summary>
/// <param name="StrSrc">字符串</param>
/// <returns>高低位转换的字节数组</returns>
public static byte[] StrToRevBytes(string StrSrc)
{
byte[] byteResults = null;
List<byte> lstBytes = null;
if (StrSrc != null)
{
if (StrSrc.Trim() != "")
{
lstBytes = new List<byte>();
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<byte> lstTemp = new List<byte>();
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;
}
/// <summary>
/// 字节数组转16进制字符串空格分隔
/// </summary>
/// <param name="byteDatas"></param>
/// <returns></returns>
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();
}
/// <summary>
/// 16进制格式字符串转字节数组
/// </summary>
/// <param name="hexStr"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 32进制数高低位对调
/// </summary>
/// <param name="value"></param>
/// <returns>字节数组</returns>
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;
}
}
}