Alexander
Alexander

Reputation: 1329

PHP: Big integer base 10 represented as string to binary string

I need to convert a really big integer that is represented as a string to a binary string (aka normal integer, but it is always bigger as normal php integer can hold) to efficiently store it in database and have a unique index on it.

The number comes from GMP (gmp_strval()) and may have different lengths, usually about 200-300 "characters" in it, so it never fits into PHP integer. The idea is to convert it into a binary string representing an integer, kind of big integer. Can I do it with PHP?

Upvotes: 0

Views: 1089

Answers (2)

Alexander
Alexander

Reputation: 1329

Found Math_BigInteger library that can do it:

$a = new Math_BigInteger($intString);
$base256IntString = $a->toBytes();

https://github.com/pear/Math_BigInteger

Upvotes: 0

AbcAeffchen
AbcAeffchen

Reputation: 15007

Sure you can do this. Remember how to convert a decimal number to binary by hand.

  1. look if the last digit is even (gives a 0) or odd (gives a 1)
  2. subtract the 1, if you get one.
  3. divide by 2. This have to be done digit by digit as in elementary school :-)
  4. repeat this until your decimalnumber become zero.

I wrote a function for this

function strMod2(array $dec)
{
    return ((int)end($dec)) % 2;
}

function strDivBy2(array $dec)
{
    $res = [];
    $carry = 0;

    if($dec[0] == '0')
        array_shift($dec);

    $len = count($dec);
    for($i = 0; $i < $len; $i++)
    {
        $num = $carry*10 + ((int)$dec[$i]);
        $carry = $num % 2;
        $num -= $carry;
        $res[] = $num / 2;
    }

    return $res;
}


function dec2bin_str($dec)
{
    $dec_arr = str_split($dec);
    $bin_arr = [];
    while(count($dec_arr) > 1 || $dec_arr[0] != 0)
    {
        array_unshift($bin_arr, strMod2($dec_arr));
        $dec_arr = strDivBy2($dec_arr);
    }

    return implode($bin_arr);
}

You can use it as

echo dec2bin_str('5');     // '101'
echo dec2bin_str('146456131894613465451');        // '1111111000001111100101101000000000000010100001100010101100101101011'

Maybe this can be done faster by using a library for big integers.

Upvotes: 1

Related Questions