将十六进制字符串解码为 4 个部分,映射到值的二进制映射
Decoding a hex string into 4 pieces that maps to a binary map of values
我正在尝试解码一个所谓的十六进制字符串。在 MS SQL 服务器 (11.0.2100) 中,数据的类型为 char(8)
.
手册中没有明确的数据解码方法,但它记录了数据包含的内容:
Given a hex string ie. 0001003F
with a length of 4. The lower byte
is on the right, the higher byte is on the left. For each of the 4
'bytes
' a reference table that maps a 'bit' to a certain truthy
value was given. A bit order is also given having the bit 0 or the bit
in right most being the 1st bit, ..., etc.
table 看起来像这样:
第一 'byte':
|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 个 tables 之后还有 3 个 'byte's ...,这 4 个 'byte's 中的每一个都应该有 8 个相等数量的 'bits')
我认为解码此数据的方法是将十六进制字符串拆分为 4 个部分,并将它们转换为宽度固定为 8 的二进制字符串。
在PHP
中,以十六进制'0001003F
'为例,第一个字节是'3F
',转换为二进制,0011 1111
(space 为清楚起见)。然后,推断第一个字节的值为:
'state foo is on', 'in state bar', ..., 'not in state bazz'
.
我也试过:hex2bin("0001003F")
但它输出 strin(4) " # "
.
这是解码此数据的正确方法吗?
(标签有误请见谅)
因为 4 个字节适合 integer type on almost all platforms (32-bit and higher), you can convert the hex string to integer, then use the bitwise operators 的存储以检查是否设置了特定位:
$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
function. The loop iterates bit numbers in range [0;31]
(starting from the least significant bit). The (1 << $bit)
expression is the value 1
shifted to the left by $bit
bits. Thus, if bit number $bit
is set, then the result of the bitwise AND operation is a non-zero integer. The result is cast to boolean类型的帮助下将十六进制字符串$hex_str
转换为整数$flags
以产生1
,如果结果不为零,和 0
否则。
很容易看出,您可以使用单个按位 AND 操作来测试多个位,例如:
// 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
我正在尝试解码一个所谓的十六进制字符串。在 MS SQL 服务器 (11.0.2100) 中,数据的类型为 char(8)
.
手册中没有明确的数据解码方法,但它记录了数据包含的内容:
Given a hex string ie.
0001003F
with a length of 4. The lower byte is on the right, the higher byte is on the left. For each of the 4 'bytes
' a reference table that maps a 'bit' to a certain truthy value was given. A bit order is also given having the bit 0 or the bit in right most being the 1st bit, ..., etc.
table 看起来像这样:
第一 'byte':
|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 个 tables 之后还有 3 个 'byte's ...,这 4 个 'byte's 中的每一个都应该有 8 个相等数量的 'bits')
我认为解码此数据的方法是将十六进制字符串拆分为 4 个部分,并将它们转换为宽度固定为 8 的二进制字符串。
在PHP
中,以十六进制'0001003F
'为例,第一个字节是'3F
',转换为二进制,0011 1111
(space 为清楚起见)。然后,推断第一个字节的值为:
'state foo is on', 'in state bar', ..., 'not in state bazz'
.
我也试过:hex2bin("0001003F")
但它输出 strin(4) " # "
.
这是解码此数据的正确方法吗?
(标签有误请见谅)
因为 4 个字节适合 integer type on almost all platforms (32-bit and higher), you can convert the hex string to integer, then use the bitwise operators 的存储以检查是否设置了特定位:
$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
function. The loop iterates bit numbers in range [0;31]
(starting from the least significant bit). The (1 << $bit)
expression is the value 1
shifted to the left by $bit
bits. Thus, if bit number $bit
is set, then the result of the bitwise AND operation is a non-zero integer. The result is cast to boolean类型的帮助下将十六进制字符串$hex_str
转换为整数$flags
以产生1
,如果结果不为零,和 0
否则。
很容易看出,您可以使用单个按位 AND 操作来测试多个位,例如:
// 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