TCP/IP/Socket/Modbus 对接常用转换(十位转十六位Hex转Byte CRC16验证 等)

TCP/IP/Socket/Modbus 对接常用转换(十位转十六位Hex转Byte CRC16验证 等)

using System;
using System.Globalization;
using System.Linq;
using System.Text;

namespace MyNamespace 
{
    public sealed class ConvertHelper
    {
        /// <summary>
        /// 字符串转16进制
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string ConvertStringToHex(string input)
        {
            byte[] byteArray = Encoding.UTF8.GetBytes(input);
            string hexString = BitConverter.ToString(byteArray);
            return hexString.Replace("-", "");
        }

        /// <summary>
        /// 字符串转换为Hex字符串
        /// </summary>
        /// <param name="s">字符串</param>
        /// <param name="encode">编码类型</param>
        /// <returns></returns>
        public static string StringToHexString(string s, Encoding encode)
        {
            var b = encode.GetBytes(s); //按照指定编码将string编程字节数组
            return b.Aggregate(string.Empty, (current, t) => current + "%" + Convert.ToString(t, 16));
        }

        /// <summary>
        /// Hex字符串转换为字符串
        /// </summary>
        /// <param name="hs">Hex字符串</param>
        /// <param name="encode">编码类型</param>
        /// <returns></returns>
        public static string HexStringToString(string hs, Encoding encode)
        {
            //以%分割字符串,并去掉空字符
            var chars = hs.Split(new[] { '%' }, StringSplitOptions.RemoveEmptyEntries);
            var b = new byte[chars.Length];
            //逐个字符变为16进制字节数据
            for (var i = 0; i < chars.Length; i++) b[i] = Convert.ToByte(chars[i], 16);

            //按照指定编码将字节数组变为字符串
            return encode.GetString(b);
        }

        /// <summary>
        /// 字符串转16进制字节数组
        /// </summary>
        /// <param name="hexString">Hex字符串</param>
        /// <returns></returns>
        public static byte[] StringToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if (hexString.Length % 2 != 0)
                hexString += " ";
            var returnBytes = new byte[hexString.Length / 2];
            for (var i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }

        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="bytes">bytes</param>
        /// <returns></returns>
        public static string BytesToHexString(byte[] bytes)
        {
            const string returnStr = "";
            return bytes == null ? returnStr : bytes.Aggregate(returnStr, (current, t) => current + t.ToString("X2"));
        }

        /// <summary>
        /// 将byte[]转换成int
        /// </summary>
        /// <param name="data">需要转换成整数的byte数组</param>
        public static int BytesToInt32(byte[] data)
        {
            //如果传入的字节数组长度小于4,则返回0
            if (data.Length < 4) return 0;

            //定义要返回的整数
            var num = 0;
            //如果传入的字节数组长度大于4,需要进行处理
            if (data.Length < 4) return num;
            //创建一个临时缓冲区
            var tempBuffer = new byte[4];
            //将传入的字节数组的前4个字节复制到临时缓冲区
            Buffer.BlockCopy(data, 0, tempBuffer, 0, 4);
            //将临时缓冲区的值转换成整数,并赋给num
            num = BitConverter.ToInt32(tempBuffer, 0);
            //返回整数
            return num;
        }

        /// <summary>
        /// bytes数据转换为float类型
        /// </summary>
        /// <param name="data">byte数据</param>
        /// <returns></returns>
        public static float ValueConvertToFloat(byte[] data)
        {
            var shuju = BytesToHexString(data);
            var num = uint.Parse(shuju, NumberStyles.AllowHexSpecifier);
            var floatValues = BitConverter.GetBytes(num);
            return BitConverter.ToSingle(floatValues, 0);
        }

        /// <summary>
        /// bytes数据转换为long类型
        /// </summary>
        /// <param name="data">byte数据</param>
        /// <returns></returns>
        public static long ValueConvertToLong(byte[] data)
        {
            var shuju = BytesToHexString(data);
            var num = ulong.Parse(shuju, NumberStyles.AllowHexSpecifier);
            return (long)num;
        }

        /// <summary>
        /// CRC16验证
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static byte[] CRC16(byte[] data)
        {
            ushort crc = 0xFFFF; //set all 1

            var len = data.Length;
            if (len <= 0)
            {
                crc = 0;
            }
            else
            {
                len--;
                uint ix;
                for (ix = 0; ix <= len; ix++)
                {
                    crc = (ushort)(crc ^ data[ix]);
                    uint iy;
                    for (iy = 0; iy <= 7; iy++)
                        if ((crc & 1) != 0)
                            crc = (ushort)((crc >> 1) ^ 0xA001);
                        else
                            crc = (ushort)(crc >> 1); //
                }
            }

            var buf1 = (byte)((crc & 0xff00) >> 8); //高位置
            var buf2 = (byte)(crc & 0x00ff); //低位置
            crc = (ushort)(buf1 << 8);
            crc += buf2;
            var strA = crc.ToString("x4");
            var result = StringToHexByte(strA);
            var b = new byte[2];
            b[0] = result[1];
            b[1] = result[0];
            return b;
        }
    }
}

调用举例:

SqlSugarHelper sugar = new SqlSugarHelper();
var db = sugar.SqlClient();

var gsList = db.Queryable<sys_gs7020>().ToList();//取出设备列表
if (gsList != null && gsList.Any() && gsList.Count > 0)//有且有值
{
    foreach (var gs in gsList)
    {
        try
        {
            string inquiry = gs.EquipAdd + gs.FunctionCode + gs.RegisterAdd + gs.RegisterNum;//拼接报文:设备地址+操作码+寄存器定地址+寄存器个数
            byte[] bt = ConvertHelper.StringToHexByte(inquiry);//字符串转十六位Hex
            byte[] crc16_byte = ConvertHelper.CRC16(bt);//CRC16验证
            string crc16_hex = ConvertHelper.BytesToHexString(crc16_byte);//byte转十六位hex字符串

            if (!string.IsNullOrWhiteSpace(gs.CRC16))
            {
                if (gs.CRC16 == crc16_hex)//二次验证
                {
                    inquiry += gs.CRC16;
                }
                else
                {
                    inquiry += crc16_hex;
                }
            }
            else
            {
                inquiry += crc16_hex;
            }

                Console.WriteLine($"发送报文: {inquiry}");//打印结果
                var buffers = ConvertHelper.StringToHexByte(inquiry);//字符串转16位Byte发送
                send.Send(buffers);//发送报文
            }
            catch (Exception ex)
            {
                Console.WriteLine($"报错: {ex.Message}");//打印结果    
                MyLog.WriteLog($"报错: {ex.Message}", ex.ToString(), LogType.error);//日志    
                continue;//继续
            }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值