php-位掩码“解码”

时间:2019-06-25 18:48:12

标签: php bit-manipulation

我想编写一个将位掩码“解码”为原始值的函数,例如
上面附有数字和文字:

  • 2 -文字_1
  • 4 -文字_2
  • 8 -Text_3
  • 16 -Text_4
  • 32 -Text_5

现在我要输入数字,例如4832 + 16),我应该得到Text_5Text_4,所以它应该返回两个数字:3216
如何获得?

3 个答案:

答案 0 :(得分:2)

PHP有一些功能可以帮助解决此问题,主要是decbin()https://www.php.net/manual/en/function.decbin.php),它将把整数转换成二进制。然后,您可以将其分解为一个数组,该数组将按照示例中的Text_值进行编号。

$input = 48;
$output = array_reverse(str_split(decbin($input)));

foreach ($output as $k => $v) {
    echo $v ? "Text_$k".PHP_EOL : "";
}

因此decbin(48)将给出110000,您可以使用str_split()将其分成以下数组:

Array
(
    [0] => 1
    [1] => 1
    [2] => 0
    [3] => 0
    [4] => 0
    [5] => 0
)

但是您可以看到这是向后的-在二进制中,我们从右到左而不是从左到右对位进行编号。因此,您需要使用array_reverse()来反转它。

然后,您有一个不错的Text_ => active (1 or 0)对数组:

Array
(
    [0] => 0
    [1] => 0
    [2] => 0
    [3] => 0
    [4] => 1
    [5] => 1
)

答案 1 :(得分:1)

我想,这是最简单,最“本机”的实现:

$array = [2 => 'Text_1', 4 => 'Text_2', 8 => 'Text_3', 16 => 'Text_4', 32 => 'Text_5'];

$number = 48;

foreach ($array as $mask => $string)
{
    if ($number & $mask)
    {
        echo "$mask: $string" . PHP_EOL;
    }
}

答案 2 :(得分:0)

另一个仅使用位运算符的选项...

unmaskMe(48);

function unmaskMe(int $bitset) {
    $bitOfsset = 0;

    while ($bitset) {
        if ($bitset & (1 << $bitOfsset)) {
            echo 'Text_' .  $bitOfsset . PHP_EOL;

            $bitset &= ~(1 << $bitOfsset);
        }

        $bitOfsset++;
    }
}

输出:

  

Text_4

     

Text_5