數值轉字節數組,以及字節數組轉數值,需要注意的是C#的本地字節序是小端模式的,而網絡字節序卻是(大端模式),所以我用到了IPAddress來進行Host和Network的轉換
為了簡單以及更好的性能,做了一些取巧的處理方式,盡量避免數組拷貝和反轉,看上去很詭異,經過簡單測試貌似沒啥問題,不敢保證百分百沒問題啊,如果有問題,望指出啊,不建議直接拿來用啊
/// <summary> /// 對BitConverter進行方法擴展 /// </summary> public static class BitConverterExtend { /// <summary> /// 得到數值的網絡字節序(大端模式)的字節數組 /// </summary> 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); } /// <summary> /// 將網絡字節序(大端模式)的字節數組轉成本地字節序(小端模式)的數值 /// </summary> 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); } /// <summary> /// 拷貝反轉 /// </summary> static byte[] CopyAndReverse(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; } 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[] value, int startIndex, int count) { return Encoding.UTF8.GetString(value, startIndex, count); } }