美文网首页程序园技术初心
字节数组格式化解析

字节数组格式化解析

作者: triplestudio | 来源:发表于2019-12-01 23:35 被阅读0次

    1. 一些实用工具方法

    有足够便捷的工具方法,则在用代码表达思想时会变得如鱼得水,一气呵成!

    public class ByteHelper
    {
        public static string BytesToHexString(byte[] bytes)
        {
            return BytesToHexString(bytes, " ");
        }
    
        public static string BytesToHexString(byte[] bytes, string span)
        {
            StringBuilder sb = new StringBuilder(bytes.Length * (2 + span.Length));
            bool isFirst = true;
            foreach (byte b in bytes)
            {
                if (isFirst)
                {
                    isFirst = false;
                }
                else
                {
                    sb.Append(span);
                }
                sb.Append(Convert.ToString(b, 16).PadLeft(2, '0').ToUpper());
            }
            return sb.ToString();
        }
    
        public static byte[] HexStringToBytes(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2).Replace(" ", ""), 16);
            return returnBytes;
        }
    
        /// <summary>
        /// 字节数组转整型
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static int GetIntValue(byte[] bytes)
        {
            return Convert.ToInt32(GetLongValue(bytes));
        }
    
        public static uint GetUnsignedIntValue(byte[] bytes)
        {
            return Convert.ToUInt32(GetUnsingedLongValue(bytes));
        }
    
        /// <summary>
        /// 将整型按小端转换成指定长度的byte数组
        /// </summary>
        /// <param name="value"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static byte[] IntToBytes(int value, int len)
        {
            byte[] bytes = new byte[len];
            string strHexValue = Convert.ToString(value, 16).PadLeft(len * 2, '0');
            for (int index = 0; index < len; index++)
            {
                bytes[index] = Convert.ToByte(strHexValue.Substring(strHexValue.Length - (index + 1) * 2, 2), 16);
            }
            return bytes;
        }
    
        public static byte[] SubBytes(byte[] bytes, int startIndex, int len)
        {
            if (startIndex + len > bytes.Length) len = bytes.Length - startIndex;
    
            byte[] subBytes = new byte[len];
            Array.Copy(bytes, startIndex, subBytes, 0, len);
            return subBytes;
        }
    
        # region 以长整型支持最多 8 个字节的整数转换
    
        /// <summary>
        /// 非 1,2,4,8 字节的其它字节转换
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static long GetIrregularLongValue(byte[] bytes)
        {
            long value = 0; // 循环读取每个字节通过移位运算完成long的4个字节拼装
            for (int count = 0; count < bytes.Length; ++count)
            {
    
                int shift = count << 3;
                value |= ((long)0xff << shift) & ((long)bytes[count] << shift);
            }
            return value;
        }
    
        /// <summary>
        /// 只考虑小端(有符号)
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static long GetLongValue(byte[] bytes)
        {
            if (bytes.Length == 1)
            {
                return (long)((sbyte)bytes[0]);
            }
            else if (bytes.Length == 2)
            {
                return (long)BitConverter.ToInt16(bytes, 0);
            }
            else if (bytes.Length == 4)
            {
                return (long)BitConverter.ToInt32(bytes, 0);
            }
            else if (bytes.Length == 8)
            {
                return (long)BitConverter.ToInt64(bytes, 0);
            }
            return GetIrregularLongValue(bytes);
        }
    
        /// <summary>
        /// 只考虑小端(无符号)
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static ulong GetUnsingedLongValue(byte[] bytes)
        {
            if (bytes.Length == 1)
            {
                return (ulong)bytes[0];
            }
            else if (bytes.Length == 2)
            {
                return (ulong)BitConverter.ToUInt16(bytes, 0);
            }
            else if (bytes.Length == 4)
            {
                return (ulong)BitConverter.ToUInt32(bytes, 0);
            }
            else if (bytes.Length == 8)
            {
                return (ulong)BitConverter.ToUInt64(bytes, 0);
            }
            return (ulong)GetIrregularLongValue(bytes);
        }
    
        #endregion
    }
    

    2. 配置定义

    通过配置来达到动态解析的目的。
    配置项通过包括几个方面:
    (1)控制解析的基础配置
    (2)业务需要的必要配置
    (3)其它扩展的配置(如样式控制等)

    {
        "数据结构":[
            { "长度":4, "标签":"温度","类型":"浮点型","大小端":"大","单位":"℃" },
            { "长度":4, "标签":"湿度","类型":"浮点型","大小端":"大","单位":"%" },
            { "长度":4, "标签":"露点","类型":"浮点型","大小端":"大","单位":"℃" },
        ],
    }
    

    3. 解析数据

    /// <summary>
    /// 解析数据
    /// 根据配置:"长度":2, "标签":"距离","类型":"整型","大小端":"大","单位":"m"
    /// </summary>
    /// <param name="data"></param>
    /// <returns></returns>
    public static JObject ParseData(byte[] data)
    {
        JObject result = new JObject();
        JArray values = new JArray();
        JArray items = GetStructConfig().Value<JArray>("数据结构");
        int startIndex = 0;
        foreach (JObject item in items)
        {
            if (startIndex >= data.Length) return null;
    
            JObject valueItem = new JObject(); 
    
            int len = item.Value<int>("长度");
            string label = item.Value<string>("标签");
            string type = item.Value<string>("类型");
            string begin = item.Value<string>("大小端");
            string unit = item.Value<string>("单位");
    
            valueItem["label"] = label;
    
    
            byte[] bs = ByteHelper.SubBytes(data, startIndex, len);
            if ("整型".Equals(type))
            {
                if ("大".Equals(begin))
                {
                    Array.Reverse(bs);
                }
                valueItem["value"] = ByteHelper.GetIntValue(bs);
            }
            else if ("浮点型".Equals(type))
            {
                if ("大".Equals(begin))
                {
                    Array.Reverse(bs);
                }
                valueItem["value"] = Math.Round(BitConverter.ToSingle(bs, 0), 2);
            }
            else if ("字符型".Equals(type))
            {
                valueItem["value"] = Encoding.Default.GetString(bs);
            }
            else
            {
                valueItem["value"] = ByteHelper.BytesToHexString(bs);
            }
    
            valueItem["label"] = label;
            valueItem["unit"] = unit;
    
            values.Add(valueItem);
            startIndex += len;
        }
        result["values"] = values;
        return result;
    }
    }
    

    相关文章

      网友评论

        本文标题:字节数组格式化解析

        本文链接:https://www.haomeiwen.com/subject/mbitgctx.html