将十六进制字符串解码为映射到值的二进制映射的4个部分


Decoding a hex string into 4 pieces that maps to a binary map of values

我试图解码一个十六进制字符串。MS SQL Server (11.0.2100)中的数据类型为char(8)

在手册中没有明确的解码数据的方法,但它记录了它所包含的内容:

给定一个十六进制字符串。长度为4的0001003F。低字节在右边,高的字节在左边。对于每一个4' bytes '是一个将'bit'映射到某个真值的引用表价值被赋予。位顺序也被给定为位0或位在最右边是第1位,…等。

表是这样的:

"字节"1:

|Bit Order  | Description   |   1               |   0               |   trigger     |
|-----------|---------------|-------------------|-------------------|---------------|
|BIT0       | state foo     | state foo is ON   | State foo is OFF  |   high level  |
|BIT1       | state bar     | in state bar      | not in state bar  |   high level  |
|                                   ... 
|BIT7       | state bazz    | in state bazz     | not in state bazz |   high level  |

(接下来的3个其他'字节'的3个表…(4个字节中的每一个应该有8个相同数量的'位')

我认为解码该数据的方式是将十六进制字符串分成4部分,并将其转换为二进制字符串宽度固定为8。

PHP中,以十六进制' 0001003F '为例,第一个字节是' 3F ',转换为二进制,0011 1111(空格表示清晰)。然后,推断第一个字节的值为:

'state foo is on', 'in state bar', ..., 'not in state bazz' .

我也尝试做:hex2bin("0001003F"),但它输出strin(4) " # "

这是解码数据的正确方法吗?

(如果标签不正确,请原谅)

由于在几乎所有平台(32位及更高)上4字节适合整数类型的存储,因此您可以将十六进制字符串转换为整数,然后使用位运算符检查是否设置了特定位:

$hex_str = '0001003F';
$flags = base_convert($hex_str, 16, 10);
foreach (range(0, 31) as $bit) {
  printf("Bit %d: %d'n", $bit, (bool) ($flags & (1 << $bit)));
}
输出

Bit 0: 1
Bit 1: 1
Bit 2: 1
Bit 3: 1
Bit 4: 1
Bit 5: 1
Bit 6: 0
...
Bit 15: 0
Bit 16: 1
Bit 17: 0
...
Bit 31: 0

如果$bit位设置为(1),则该位对应的状态为on

代码通过base_convert函数将十六进制字符串$hex_str转换为整数$flags。循环迭代[0;31]范围内的位数(从最低有效位开始)。(1 << $bit)表达式是1的值左移了$bit位。因此,如果设置了位号$bit,则按位运算的结果是一个非零整数。结果被强制转换为布尔类型以产生1,如果结果不为零,则产生0

很容易看出,您可以使用单个按位操作来测试多个位,例如:

// Check if at least one of three bits is set, 3rd, 10th, or 11th
$mask = (1 << 3) | (1 << 10) | (1 << 11);
if ($flags & $mask)
  printf("At least one of the bits from mask 0x%x is set'n", $mask);
输出

At least one of the bits from mask 0xc08 is set