最近的工作中,需要接触到一些硬件设备,处理这些设备的通讯,因此需要进行一些进制的转换。
其实,二进制、十六进制这些基本的知识,在我们刚学编程的时候,基础课应该已经讲过的了。但是,包括我自己在内,当时也仅仅是知道一般的换算规则,但是具体怎么应用,在c#中又是如何表示,也是近期才有比较深的体会。
具体的知识,各位就自己查看相关的基础知识了,这里我只给出自己在工作中的体会和实际的类库。
首先,先解释下C#的类型。一般,我们常用的有 byte、short、int(Int32)、long(Int64)。这几个在底层的一些通讯中也是最常用到的。以下做了一个比较,大家一看便知:
因此有:
2个十六进制 = 1个字节 = 1个byte = 8位
4个十六进制 = 2个字节 = 1个short = 16位
8个十六进制 = 4个字节 = 1个int = 32位
16个十六进制= 8个字节 = 1个long = 64位
一个ASCII = 1个字节 = 2个十六进制
一个汉字 = 2个字节 = 4个十六进制
其他无符号的整数等,自己参考上述转换。
使用C#的Com口API或者Tcp API等,返回的数据一般是一个byte数组,因此,我们便可以把想要的数据转换为相关的进制或者字符串。
一般我们的硬件会有8位寄存器,16位寄存器,32位寄存器,64位寄存器。而厂商提供给我们的协议一般是用16进制表示,因此我们很容易就明白一个采用16位寄存器返回的数据:12FA3B4E,就是表示在设备中有两个寄存器返回了数据。
以下提供常用的进制转换的API:
16进制转其他进制
2 /// 十六进制转二进制
3 /// </summary>
4 /// <example>
5 /// <code>
6 /// //result的结果为46
7 /// int result = NumberHelper.Hex2Dec("2E");
8 /// </code>
9 /// </example>
10 /// <param name="hex">16进制字符串</param>
11 /// <returns>返回16进制对应的十进制数值</returns>
12 public static int Hex2Dec(string hex)
13 {
14 return Convert.ToInt32(hex, 16);
15 }
16
17 /// <summary>
18 /// 十六进制转二进制
19 /// </summary>
20 /// <example>
21 /// <code>
22 /// //result的结果为101110
23 /// string result = NumberHelper.Hex2Bin("2E");
24 /// </code>
25 /// </example>
26 /// <param name="hex">16进制字符串</param>
27 /// <returns>返回16进制对应的2进制字符串</returns>
28 public static string Hex2Bin(string hex)
29 {
30 return Dec2Bin(Hex2Dec(hex));
31 }
32
33 /// <summary>
34 /// 十六进制转字节数组
35 /// </summary>
36 /// <example>
37 /// <code>
38 /// //result的结果为一个长度为2的字节数组
39 /// //其中result[0]=46,result[1]=61
40 /// byte[] result = NumberHelper.Hex2Bin("2E3D");
41 /// </code>
42 /// </example>
43 /// <param name="hex">16进制字符串</param>
44 /// <returns>返回16进制对应的字节数组</returns>
45 public static byte[] Hex2Bytes(string hex)
46 {
47 MatchCollection mc = Regex.Matches(hex, @"(?i)[\da-f]{2}");
48 return (from Match m in mc select Convert.ToByte(m.Value, 16)).ToArray();
49
50 //hexString = hexString.Replace(" ", "");
51 //if ((hexString.Length % 2) != 0)
52 // hexString += " ";
53 //byte[] returnBytes = new byte[hexString.Length / 2];
54 //for (int i = 0; i < returnBytes.Length; i++)
55 // returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
56 //return returnBytes;
57 }
10进制转其他进制
2 /// 十进制转二进制
3 /// </summary>
4 /// <example>
5 /// <code>
6 /// //result的结果为101110
7 /// string result = NumberHelper.Dec2Bin("46");
8 /// </code>
9 /// </example>
10 /// <param name="value">十进制数值</param>
11 /// <returns>返回10进制数值对应的2进制字符串</returns>
12 public static string Dec2Bin(int value)
13 {
14 return Convert.ToString(value, 2);
15 }
16
17 /// <summary>
18 /// 十进制转十六进制
19 /// </summary>
20 /// <example>
21 /// <code>
22 /// //result的结果为2E
23 /// string result = NumberHelper.Dec2Bin("46");
24 /// </code>
25 /// </example>
26 /// <param name="value">十进制数值</param>
27 /// <returns>返回10进制数值对应的16进制字符串</returns>
28 public static string Dec2Hex(int value)
29 {
30 return Convert.ToString(value, 16).ToUpper();
31 }
32
33 /// <summary>
34 /// 十进制转十六进制:格式化十六进制为指定位数,不足位数左边补0
35 /// </summary>
36 /// <example>
37 /// <code>
38 /// //result的结果为002E
39 /// string result = NumberHelper.Dec2Bin("46",4);
40 /// </code>
41 /// </example>
42 /// <param name="value">十进制数值</param>
43 /// <param name="formatLength">十六进制结果的总长度</param>
44 /// <returns>返回10进制数值对应的指定长度的16进制字符串</returns>
45 public static string Dec2Hex(int value, int formatLength)
46 {
47 string hex = Dec2Hex(value);
48 if (hex.Length >= formatLength) return hex;
49 return hex.PadLeft(formatLength, '0');
50 }
2进制转为其他进制
2 /// 二进制转十进制
3 /// </summary>
4 /// <example>
5 /// <code>
6 /// //result的结果为46
7 /// int result = NumberHelper.Bin2Dec("101110");
8 /// </code>
9 /// </example>
10 /// <param name="bin">二进制字符串</param>
11 /// <returns>返回2进制字符串对应的10进制值</returns>
12 public static int Bin2Dec(string bin)
13 {
14 return Convert.ToInt32(bin, 2);
15 }
16
17 /// <summary>
18 /// 二进制转十六进制
19 /// </summary>
20 /// <example>
21 /// <code>
22 /// //result的结果为2E
23 /// string result = NumberHelper.Bin2Hex("101110");
24 /// </code>
25 /// </example>
26 /// <param name="bin">二进制字符串</param>
27 /// <returns>返回2进制字符串对应的16进制字符串</returns>
28 public static string Bin2Hex(string bin)
29 {
30 return Dec2Hex(Bin2Dec(bin));
31 }
单字节转为其他进制
2 /// Byte转16进制
3 /// </summary>
4 /// <example>
5 /// <code>
6 /// byte b = 128;
7 /// string hex = NumberHelper.Byte2Hex(b);
8 /// Console.WriteLine(hex);//输出结果为80
9 /// </code>
10 /// </example>
11 /// <param name="b">一个字节</param>
12 /// <returns>返回对应的16进制字符串</returns>
13 public static string Byte2Hex(byte b)
14 {
15 return b.ToString("X2");
16 }
17
18 /// <summary>
19 /// 单字节转换为2进制数值
20 /// </summary>
21 /// <example>
22 /// <code>
23 /// byte b = 128;
24 /// string bin = NumberHelper.Byte2Bin(b);
25 /// Console.WriteLine(bin);//输出结果为10000000
26 /// </code>
27 /// </example>
28 /// <param name="b">一个字节</param>
29 /// <returns>返回对应的2进制字符串</returns>
30 public static string Byte2Bin(byte b)
31 {
32 return Dec2Bin(b);
33 }
多个字节转为其他进制
2 /// 字节数组转ASCII
3 /// </summary>
4 /// <example>
5 /// <code>
6 /// byte[] buffer = new byte[] {65,66,67};
7 /// string result = NumberHelper.Bytes2ASCII(buffer);
8 /// Console.WriteLine(result);//结果输出:ABC
9 /// </code>
10 /// </example>
11 /// <param name="bytes">字节数组</param>
12 /// <returns>返回该字节数组对应的ASCII码字符串</returns>
13 public static string Bytes2ASCII(byte[] bytes)
14 {
15 return Encoding.ASCII.GetString(bytes, 0, bytes.Length);
16 }
17
18 /// <summary>
19 /// 字节数组转十六进制
20 /// </summary>
21 /// <example>
22 /// <code>
23 /// byte[] buffer = new byte[] { 65, 66, 67 };
24 /// string result = NumberHelper.Bytes2Hex(buffer);
25 /// Console.WriteLine(result);//结果输出:414243
26 /// </code>
27 /// </example>
28 /// <param name="bytes">字节数组</param>
29 /// <returns>返回该字节数组对应的16进制字符串</returns>
30 public static string Bytes2Hex(byte[] bytes)
31 {
32 string returnStr = "";
33 if (bytes != null)
34 {
35 for (int i = 0; i < bytes.Length; i++)
36 {
37 returnStr += bytes[i].ToString("X2");
38 }
39 }
40 return returnStr;
41 }
42
43 /// <summary>
44 /// 将两个字节转换为十六进制数
45 /// </summary>
46 /// <example>
47 /// <code>
48 /// byte[] buffer = new byte[] { 65, 66 };
49 ///
50 /// //高位在前,低位在后
51 /// string result = NumberHelper.Bytes2Hex(buffer[0],buffer[1]);
52 /// Console.WriteLine(result);//结果输出:4142
53 ///
54 /// //低位在前,高位在后
55 /// result = NumberHelper.Bytes2Hex(buffer[1], buffer[0]);
56 /// Console.WriteLine(result);//结果输出:4241
57 /// </code>
58 /// </example>
59 /// <param name="hByte">高字节</param>
60 /// <param name="lByte">低字节</param>
61 /// <returns>返回该两个字节对应的16进制数结果</returns>
62 public static string Bytes2Hex(byte hByte, byte lByte)
63 {
64 return Byte2Hex(hByte) + Byte2Hex(lByte);
65 }
66
67 /// <summary>
68 /// 将两个字节转换为十进制数
69 /// </summary>
70 /// <example>
71 /// <code>
72 /// byte[] buffer = new byte[] { 65, 66 };
73 ///
74 /// //高位在前,低位在后
75 /// int result = NumberHelper.Bytes2Dec(buffer[0], buffer[1]);
76 /// Console.WriteLine(result);//结果输出:16706
77 ///
78 /// //低位在前,高位在后
79 /// result = NumberHelper.Bytes2Dec(buffer[1], buffer[0]);
80 /// Console.WriteLine(result);//结果输出:16961
81 /// </code>
82 /// </example>
83 /// <param name="hByte">高字节</param>
84 /// <param name="lByte">低字节</param>
85 /// <returns></returns>
86 public static int Bytes2Dec(byte hByte, byte lByte)
87 {
88 return hByte << 8 | lByte;
89 }
90
91 /// <summary>
92 /// 将两个字节(补码表示)转换为十进制数,如果是补码,则第一个bit为1则表示负数
93 /// </summary>
94 /// <example>
95 /// <code>
96 /// byte[] buffer = new byte[] { 255, 66 };
97 ///
98 /// //高位在前,低位在后
99 /// int result = NumberHelper.Bytes2Dec(buffer[0], buffer[1],false);
100 /// Console.WriteLine(result);//结果输出:65346
101 ///
102 /// //高位在前,低位在后
103 /// result = NumberHelper.Bytes2Dec(buffer[0], buffer[1], true);
104 /// Console.WriteLine(result);//结果输出:-190
105 /// </code>
106 /// </example>
107 /// <param name="hByte">高位字节</param>
108 /// <param name="lByte">低位字节</param>
109 /// <param name="isRadix">是否是采用补码表示形式</param>
110 /// <returns>返回对应的10进制数值</returns>
111 public static int Bytes2Dec(byte hByte, byte lByte, bool isRadix)
112 {
113 var v = (ushort)(hByte << 8 | lByte);//合并高地位为16进制
114 if (isRadix)
115 {
116 if (hByte > 127)
117 {
118 v = (ushort)~v; //按位取反
119 v = (ushort)(v + 1); //得到补码
120 return -1 * v;
121 }
122 }
123 return v;
124 }