8

I have seen a code that converts integer into byte array. Below is the code on How to convert integer to byte array in php 3 (How to convert integer to byte array in php):

<?php

$i = 123456;
$ar = unpack("C*", pack("L", $i));

print_r($ar);
?>

The above code will output:

//output:
Array
(
   [1] => 64
   [2] => 226
   [3] => 1
   [4] => 0
)

But my problem right now is how to reverse this process. Meaning converting from byte array into integer. In the case above, the output will be 123456

Can anybody help me with this. I would be a great help. Thanks ahead.

Community
  • 1
  • 1
gchimuel
  • 527
  • 1
  • 5
  • 9

3 Answers3

11

Why not treat it like the math problem it is?

$i = ($ar[3]<<24) + ($ar[2]<<16) + ($ar[1]<<8) + $ar[0];
n0099
  • 520
  • 1
  • 4
  • 12
PRB
  • 484
  • 2
  • 5
  • 1
    wow, this solve my problem but I change the code into: $i = ($ar[4]<<24) + ($ar[3]<<16) + ($ar[2]<<8) + ($ar[1]); since $ar[0] doesn't exist and when no parentheses is added between plus sign it will return 0 value. but thanks. – gchimuel Oct 02 '12 at 03:37
  • @gchimuel The parentheses around last part `$ar[0]` is unnecessary, other parts is. – n0099 Dec 23 '22 at 14:19
5

Since L is four bytes long, you know the number of elements of the array. Therefore you can simply perform the operation is reverse:

$ar = [64,226,1,0];
$i = unpack("L",pack("C*",$ar[3],$ar[2],$ar[1],$ar[0]));
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592
  • You can also do `unpack('L', pack('C*', ...array_reverse($ar)))` if you can ensure that $ar have 4 items and being indexed from 0 to 3. – n0099 Dec 23 '22 at 13:59
  • Also note the output of `unpack('C*', $someBytesArray)` will starts index from 1, so you should wrap `array_values()` on it. – n0099 Dec 23 '22 at 13:59
  • The meaning of `array_reverse()` or writing literal `$ar[3], ..., $ar[0]` is to convert byte order between big and small endian, if you can ensure the same endian is used through `pack()` to `unpack()`, you don't have to reverse them. – n0099 Dec 23 '22 at 14:23
4

In order to get a signed 4-byte value in PHP you need to do this:

    $temp = ($ar[0]<<24) + ($ar[1]<<16) + ($ar[2]<<8) + $ar[3];
    if($temp >= 2147483648)
         $temp -= 4294967296;
n0099
  • 520
  • 1
  • 4
  • 12
ricozinn
  • 131
  • 1
  • 8
  • 1
    Worth to mention that this workaround is needed for `x64` builds of PHP (except Windows ones). And there is one mistake in the code. The comparison must be `greater or equal` instead of just `greater`. – Denis V Oct 16 '14 at 14:49