How to convert bin to integer in PHP?

I have a project in which I need to convert a byte into an integer:

<?php
$a=md5("hello",true);
echo $a[15]*1.0/255.0;

The second parameter of md5 is set to true in order to return a binary md5 of “hello” instead of a hexical string(32 characters), according to the description of the official php document.   But I really do not know what the binary format is. Fortunately, we can use the gettype function to get the type of a php variable.

<?php
echo gettype(md5("hello"));
echo gettype(md5("hello",true));

Interestingly, whether I add the second parameter for md5 or not, the type of the return value is the same:string. The returned value of md5(“hello”) is a string of 32 characters while the returned value of md5(“hello”,true) is a string of 16 characters,in which some characters are unprintable. The type of $a[15] is also string. If we set the second parameter of md5 raw_output to true, the last element $a[15] is not a number(not in ‘0’-‘9′) so it produces an error  when doing the calculation(“Warning: A non-numeric value encountered in xxx”). How to convert $a[15]( the binary) into an integer? At first, I thought of bindec:

$a=md5("hello",true);
echo bindec($a[15]);

However, the output is “0”, which is obviously not what I want. In fact, bindec converts a binary representation of a string(such as “1011”) to a number(11), while $a[15] is not “1” or “0” or some combination of “1” and “0” so bindec does not work and just returns 0.

The correct way to convert binary data to integer(s) is using unpack.

var_dump (unpack("C",$a[15]));

The second parameter of unpack is a string. unpack converts the characters of the string into integers according to the first format parameter. The return value of unpack is an associative array, the keys start from 1(1,2,…). In our case, the binary data is a string of 1 character so the resulting array has only one element. If the string to be converted has multiple characters, the resulting array has multiple items, each one of which is an integer of the corresponding character in the string.

var_dump (unpack("C*","\x01\xBB"));
//array(2) {
  [1]=>
  int(1)
  [2]=>
  int(187)
}

This case reminds me of the difference of type of variable between php and C.  In C, a string is a concatenation of multiple characters(bytes) while in php, the element of string is also string. We cannot take a string of 1 character as a byte and directly use it as an (unsigned or signed) number. In php, we cannot even find the size of a variable in bytes. The sizeof function in php is used to get the number of elements(not bytes) of an array, while in C, we can use sizeof to accurately get the memory allocated for a variable. Variables in php are internally implemented by the _zval_struct type. You can use debug_zval_dump to print the internal information of a php variable.

Posted in

Leave a Reply