C# BitConverter扩展类 处理网络字节序

发布时间 2023-08-16 14:14:08作者: Mr_Xul
using System;
using System.Linq;
using System.Net;
using System.Text;

namespace Common
{
    /// <summary>
    /// 对BitConverter进行方法扩展
    /// </summary>
    public static class BitConverterExtend
    {
        // 得到数值的网络字节序(大端模式)的字节数组
        public static byte[] GetBytes_Network(this short num)
        {
            return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(num));
        }
        public static byte[] GetBytes_Network(this ushort num)
        {
            return ((short)num).GetBytes_Network();  //这样比反转数组快
        }
        public static byte[] GetBytes_Network(this int num)
        {
            return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(num));
        }
        public static byte[] GetBytes_Network(this uint num)
        {
            return ((int)num).GetBytes_Network();
        }
        public static byte[] GetBytes_Network(this long num)
        {
            return BitConverter.GetBytes(IPAddress.HostToNetworkOrder(num));
        }
        public static byte[] GetBytes_Network(this ulong num)
        {
            return ((long)num).GetBytes_Network();
        }
        public static byte[] GetBytes_Network(this float num)
        {
            return BitConverter.GetBytes(num).Reverse().ToArray();
        }
        public static byte[] GetBytes_Network(this double num)
        {
            return BitConverter.GetBytes(num).Reverse().ToArray();
        }
        public static byte[] GetBytes_UTF8(this string value)
        {
            return Encoding.UTF8.GetBytes(value);
        }

        // 将网络字节序(大端模式)的字节数组转成本地字节序(小端模式)的数值
        public static short ToInt16_ByNetworkBytes(this byte[] networkBytes, int startIndex)
        {
            return IPAddress.NetworkToHostOrder(BitConverter.ToInt16(networkBytes, startIndex));  //传入引用和起始索引,减少一个数组拷贝
        }
        public static ushort ToUInt16_ByNetworkBytes(this byte[] networkBytes, int startIndex)
        {
            return (ushort)((networkBytes[startIndex++] << 8) | networkBytes[startIndex]); //直接自己按位操作,这样最快
        }
        public static int ToInt32_ByNetworkBytes(this byte[] networkBytes, int startIndex)
        {
            return IPAddress.NetworkToHostOrder(BitConverter.ToInt32(networkBytes, startIndex));
        }
        public static uint ToUInt32_ByNetworkBytes(this byte[] networkBytes, int startIndex)
        {
            return (uint)((networkBytes[startIndex++] << 24) | (networkBytes[startIndex++] << 16)
                | (networkBytes[startIndex++] << 8) | networkBytes[startIndex]);
        }
        public static long ToInt64_ByNetworkBytes(this byte[] networkBytes, int startIndex)
        {
            return IPAddress.NetworkToHostOrder(BitConverter.ToInt64(networkBytes, startIndex));
        }
        public static ulong ToUInt64_ByNetworkBytes(this byte[] networkBytes, int startIndex)
        {
            return (ulong)((networkBytes[startIndex++] << 56) | (networkBytes[startIndex++] << 48)
                | (networkBytes[startIndex++] << 40) | (networkBytes[startIndex++] << 32)
                | (networkBytes[startIndex++] << 24) | (networkBytes[startIndex++] << 16)
                | (networkBytes[startIndex++] << 8) | networkBytes[startIndex]);
        }
        public static float ToFloat_ByNetworkBytes(this byte[] networkBytes, int startIndex)
        {
            return BitConverter.ToSingle(CopyAndReverse(networkBytes, startIndex, 4), 0);
        }
        public static double ToDouble_ByNetworkBytes(this byte[] networkBytes, int startIndex)
        {
            return BitConverter.ToDouble(CopyAndReverse(networkBytes, startIndex, 8), 0);
        }
        public static string GetString_UTF8(this byte[] networkBytes, int startIndex, int count)
        {
            return Encoding.UTF8.GetString(networkBytes, startIndex, count);
        }

        /// <summary>
        /// 反转拷贝
        /// </summary>
        /// <param name="networkBytes"></param>
        /// <param name="startIndex"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static byte[] CopyAndReverse(this byte[] networkBytes, int startIndex, int len)
        {
            byte[] bs = new byte[len];
            for (int i = 0; i < len; i++)
            {
                bs[len - 1 - i] = networkBytes[startIndex + i];  //反转拷贝
            }
            return bs;
        }
        /// <summary>
        /// byte数组转ushort数组(大端)
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static ushort[] BytesToUshorts(this byte[] bytes)
        {
            if (bytes != null)
            {
                ushort[] ushorts = new ushort[bytes.Length / 2];
                for (int i = 0; i < ushorts.Length; i++)
                {
                    ushorts[i] = ToUInt16_ByNetworkBytes(bytes, i * 2);
                }
                return ushorts;
            }
            else
            {
                return null;
            }
        }
        /// <summary>
        /// ushort数组转byte数组(大端)
        /// </summary>
        /// <param name="shorts"></param>
        /// <returns></returns>
        public static byte[] UshortsToBytes(this ushort[] ushorts)
        {
            if (ushorts != null)
            {
                byte[] bytes = new byte[ushorts.Length * 2];
                for (int i = 0; i < ushorts.Length; i++)
                {
                    byte[] arr = GetBytes_Network(ushorts[i]);
                    bytes[i * 2] = arr[0];
                    bytes[i * 2 + 1] = arr[1];
                }
                return bytes;
            }
            else
            {
                return null;
            }
        }
    }
}