首页 > 解决方案 > 如何从十六进制字符串中获取位范围并将其转换为整数?

问题描述

我问这个问题,因为找不到这种特殊情况的解决方案。

我需要从十六进制字符串和给定的位范围中提取值(作为 int 或字节)。例如:

hexString = "0x34840A00"

位(来自计算):00110100 10000100 00001 010 00000000

现在我需要从 8 到 10 的位:010

现在转换为 int/byte 值。有什么帮助吗?我在这里努力理解位操作。

标签: c#stringrangehexbit

解决方案


您可以首先使用Convert.FromHexString(hexString)从您的十六进制字符串中获取字节。然后您可以使用不安全的指针或BitConverter.ToInt32()将所述字节转换为 32 位整数,然后您可以对其应用位移位和其他按位操作来提取您需要的位。例如:

string hexString = "0x34840A00";
byte[] bytes = Convert.FromHexString(hexString);
int myInt = BitConverter.ToInt32(bytes, 0);
// myInt looks like this 00110100 10000100 00001010 00000000
// now shift by 8 bits to the right
myInt >>= 8;
// now it looks like this 00000000 00110100 10000100 00001010
// to get the value of the last 3 bits we need to set the first 29 bits to 0
// so we AND them together with 29 0's followed by 3 1's:
myInt &= 0x00000007;
// which results in the following bits:
// 00000000 00000000 00000000 00000010
// leaving you with an integer of the value 010 in binary or 2 in decimal

移位和 AND-ing 始终遵循相同的规则:

  1. 如果您想要从索引开始的位n(从最右边/最低有效位开始计算),则按位右移n(在您的示例中n=8(您不关心最右边的 8 位))。
  2. m是您想要从位置开始的位数n(在您的示例中,您想要保留 3 位010)。AND 结果与整数一起2^m - 1。在您的示例m=3中,这将是2^3-1 = 8-1 = 7. 因此我们做myInt &= 0x00000007;或简而言之myInt &= 0x7;

编辑:对于旧的 .NET 版本和简化

string hexString = "0x34840A00";
int myInt = Convert.ToInt32(hexString, 16);
// myInt looks like this 00110100 10000100 00001010 00000000
// now shift by 8 bits to the right
myInt >>= 8;
// now it looks like this 00000000 00110100 10000100 00001010
// to get the value of the last 3 bits we need to set the first 29 bits to 0
// so we AND them together with 29 0's followed by 3 1's:
myInt &= 0x00000007;
// which results in the following bits:
// 00000000 00000000 00000000 00000010
// leaving you with an integer of the value 010 in binary or 2 in decimal

因此,可重用(并且非常快)的方法将是这样的方法:

private static int GetBitsFromHexString(string hexString, int startIndexFromRight, int bitsToKeep)
{
    int result = Convert.ToInt32(hexString, 16);
    // shift by startIndexFromRight bits to the right
    result >>= startIndexFromRight;
    // AND the bits together with 32 - bitsToKeep 0's followed by bitsToKeep 1's:
    int bitmask = (1 << bitsToKeep) - 1; // is the same as 2^bitsToKeep - 1.
    // apply bitmask
    result &= bitmask;
    return result;
}

你会在你的例子中这样称呼它:

int result = GetBitsFromHexString("0x34840A00", 8, 3);
// result is 2 or 010 in binary 

推荐阅读