我有一个API,它通过网络返回一个byte [],表示有关设备的信息。
格式为15ab1234cd \ r \ n,其中前2个字符是消息中数据量的十六进制表示。
我知道我可以通过ASCIIEncoding.ASCII.GetString
将其转换为字符串,然后使用Convert.ToInt32(string.Substring(0, 2), 16)
来实现此目的。但是整个程序在我编写的整个程序的整个生命周期中都保留了一个字节数组,并且我不想仅仅为了获取数据包长度而转换为字符串。
有关将十六进制格式的字符数组转换为C#中的int的建议吗?
答案 0 :(得分:2)
没有.Net提供的功能。将前2个字节转换为带Encoding.GetString的字符串是非常易读的(可能不是最佳性能):
var hexValue = ASCIIEncoding.ASCII.GetString(byteData, 0, 2);
var intValue = Convert.ToInt32(hexValue, 16);
您可以轻松编写转换代码(将'0'-'9'
和'a'-'f'
/ 'A'-'F'
范围映射到相应的整数值并加在一起。
以下是严格用于娱乐目的的单一声明转换。得到的lambda(在样本中((byte)'0',(byte)'A')
之前需要2个字节的参数,假设它们是ASCII字符并转换为整数。
((Func<Func<char,int>, Func<byte, byte, int>>)
(charToInt=> (c, c1)=>
charToInt(char.ToUpper((char)c)) * 16 + charToInt(char.ToUpper((char)c1))))
((Func<char, int>)(
c => c >= '0' && c <='9' ? c-'0' : c >='A' && c <= 'F' ? c - 'A' + 10 : 0))
((byte)'0',(byte)'A')
答案 1 :(得分:1)
如果您知道前两个值是有效的十六进制字符(0-9,A-Z,a-z),则可以使用逻辑运算符转换为十六进制值。
int GetIntFromHexBytes(byte[] s, int start, int length)
{
int ret = 0;
for (int i = start; i < start+length; i++)
{
ret <<= 4;
ret |= (byte)((s[i] & 0x0f) + ((s[i] & 0x40) >> 6) * 9);
}
return ret;
}
(这是有效的,因为c & 0x0f
会返回4个最低有效位,对于值&#39; 0&#39; - &#39; 9&#39;以及从1开始,其范围为0-9 - 6个大写和小写字母(&#39; a&#39; - &#39;&#39;&#39; A&#39; - &#39; Z&#39;)。{{1} }对于数字字符为0,对于字母字符为0x40;向右移动六个字符为数字字符提供0值,为字母字符提供1个。向左移动并乘以9将为字母添加9的偏差以映射AF和af从1-6到10-15。)
给定字节数组:
s[i] & 0x40
根据需要,调用byte[] b = { (byte)'7', (byte)'f', (byte)'1', (byte)'c' };
将返回127(0x7f),即数组的前两个字节。
作为一个警告:这种方法没有边界检查。如果需要,可以在循环中添加一个检查,以确保输入字节是有效的十六进制字符。