Hello, Again!

31 12 2014

Flickr: by rdohms

I chanced upon some amusing JAVA code today and decided to translate it into PHP. Here’s the code:

$bignum = 4946144450195624;
for ($long = $bignum; $long > 0; $long >>= 5){
 $result = (( $long & 31 | 64) % 95) + 32;
 echo chr($result);
// hello world

The most interesting part of course is not the result but rather how the solution achieves its result. Note: this code needs to run on a 64bit platform. You can also see a live demo here.

If you rewrite $bignum as a binary number and then group every 5 bits (that’s what the ‘>>= 5’ is about) compare the numerical values with an ASCII table of characters and you’ll see that each grouping correlates with the numerical value of one of the characters in the above greeting.

Some may think that this code is silly but I think it does have a value. The example reminds one that computers are fundamentally about operations performed with binary numbers. Most of the time, we are oblivious about what goes on behind the scenes, until the code ceases to perform correctly just because one has moved from using a 64-bit platform to one that is 32 bits. $bignum is too big for 32 bits unless one is using a system that handles big numbers as if they were strings. Let’s try PHP’s BC Math extension, as follows:

$bignum = '4946144450195624';
$a = '';
$b = '';
for ($long = $bignum; bccomp($long,0) == 1; $long >>= 5){
 $a = (string) ($long & 31 | 64);
 $b = bcmod($a ,'95');

 $result = bcadd($b, '32');
 echo chr($result);

The advantage of the BC Math extension is that it uses arbitrary precision which should make the code run even on a 32 bit platform. Except that with this particular coding challenge, it fails to deliver! The extension lacks support for operations involving bits, such as the right-bit shifting  as well as the bit ANDing and ORing.

Another extension, GMP, seems to have almost all the necessary support except for one important omission; the extension also lacks support for bit-shifting to the right.  There is a way to surmount that obstacle, if you.recall that bit-shifting to the right is really short-hand for division with a divisor set to some power of two.

$bignum = '4946144450195624';
$a = '';
$d = '';
for ( ;
gmp_cmp( $bignum, '0' ) >= 1;
$bignum = gmp_div( $bignum,  gmp_pow( '2', '5' )  )  )
$d = gmp_or( gmp_and( $bignum, '31' ), '64' );
$a = gmp_mod( $d , '95' );
$b = '32';
$result = gmp_add( $a,  $b );
$str = gmp_strval( $result );
echo chr( $str );

I ran this code with PHP5.4 on a 32bit box and it ran perfectly.  I haven’t really paid a whole lot of attention to GMP, but now I’m convinced it’s the way to go when dealing with terribly large numbers and one is using PHP.

Recommended Reading

This work is licensed under a Creative Commons License




Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: