Reputation: 3374
I need to convert an unsigned integer into a 4 byte string to send on a socket.
I have the following code and it works, but it feels... disgusting.
/**
* @param $int
* @return string
*/
function intToFourByteString( $int ) {
$four = floor($int / pow(2, 24));
$int = $int - ($four * pow(2, 24));
$three = floor($int / pow(2, 16));
$int = $int - ($three * pow(2, 16));
$two = floor($int / pow(2, 8));
$int = $int - ($two * pow(2, 8));
$one = $int;
return chr($four) . chr($three) . chr($two) . chr($one);
}
My friend who uses C says I should be able to do this with bitshifts but I don't know how and he isn't familiar enough with PHP to be helpful. Any help would be appreciated.
To do the reverse I already have the following code
/**
* @param $string
* @return int
*/
function fourByteStringToInt( $string ) {
if( strlen($string) != 4 ) {
throw new \InvalidArgumentException('String to parse must be 4 bytes exactly');
}
return (ord($string[0]) << 24) + (ord($string[1]) << 16) + (ord($string[2]) << 8) + ord($string[3]);
}
Upvotes: 2
Views: 3927
Reputation: 214959
This is actually as simple as
$str = pack('N', $int);
see pack
. And the reverse:
$int = unpack('N', $str)[1];
If you're curious how to do packing using bit shifts, it goes like this:
function intToFourByteString( $int ) {
return
chr($int >> 24 & 0xFF).
chr($int >> 16 & 0xFF).
chr($int >> 8 & 0xFF).
chr($int >> 0 & 0xFF);
}
Basically, shift eight bits each time and mask with 0xFF (=255) to remove high-order bits.
Upvotes: 5