2

For example I have an integer

$mask = 210;

which in binary is

$binary = decbin($mask); // "11010010"

Now I want to convert this ($mask or $binary) to an array with the indexes which is true:

$expected = [2, 5, 7, 8];

What is the best way to do this?

Phoenix
  • 756
  • 1
  • 7
  • 22
  • So, show us what have you tried. – u_mulder Dec 22 '15 at 08:09
  • 1
    what is your logic for $expected = [2, 5, 7, 8]; – Krishna Gupta Dec 22 '15 at 08:10
  • Split `$binary` to an array, push a 0 to give yourself offsets from 1 rather than from zero, reverse it, filter to remove falsey values, and get the keys – Mark Baker Dec 22 '15 at 08:10
  • @u_mulder only str_split came to my mind and then use foreach to loop the chars array to push the indexes to an new array if the value is "1", but I guess this would not be efficient, comparing to bitwise operations... – Phoenix Dec 22 '15 at 08:13
  • @Phoenix I assume you are trying to create a bitmask for permission storage. If that's not the case, please update the question with your intended goal and I'll vote to reopen. – Gordon Dec 22 '15 at 08:17

2 Answers2

1

You can do this manually:

$expected = array();

$mask = 210;
$binary = strrev(decbin($mask)); // strrev reverts the string

for ($i = 0; $i < strlen($binary); $i++)
{
    if ($binary[$i] === '1') $expected[] = ($i + 1);
}

Working IDEOne demo.

Important note: bits are usually being numerated from zero. So, the correct answer would be "1 4 6 7". Change ($i + 1) to $i in order to achieve this result.

Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101
0

Split $binary to an array, push a 0 to give yourself offsets from 1 rather than from zero, reverse it, filter to remove falsey values, and get the keys

$mask = 210;
$binary = decbin($mask); // "11010010"

$tmp = str_split($binary, 1);
$tmp[] = 0;
$expected = array_keys(
    array_filter(
        array_reverse($tmp)
    )
);

var_dump($expected);

Demo

Mark Baker
  • 209,507
  • 32
  • 346
  • 385