开发者

php5 pack is broken on x84_64 env

   pack('H*', dechex(12345678900)) /* on 32bit */  
!= pack('H开发者_JAVA技巧*', dechex(12345678900)) /* on 64bit */

why ?


I don't know how to fix it, but I think I know why this is happening. No bug here - straigt out from the manual http://php.net/manual/en/function.dechex.php

The largest number that can be converted is 4294967295 in decimal resulting to "ffffffff"

I do not know what exactly is happening "inside" php, but you probably are causing 32 bit unsigned integer to overflow (12,345,678,900 > 4,294,967,295). Since on 64 bit this limit should be 18,446,744,073,709,551,615, dechex is returning "correct" values (32 vs 64 bit diffirence doesn't seem to be documented and I might be wrong since I don't have 64 bit system for testing).

//Edit:

As a last resort you could use GMP extesion to make your own hecdex function for 32 bit system, but that is going to produce lots and lots of overhead. Probably going to be one of the slowest implementations known to the modern programming.

//Edit2:

Wrote a function using BCMath, I'm on a Windows at the moment and was struggling finding correct dll for GMP.

function dechex32($i) {
    //Cast string
    $i = (string)$i;
    //Initialize result string
    $r = NULL;
    //Map hex values 0-9, a-f to array keys
    $hex = array_merge(range(0, 9), range('a', 'f'));
        //While input is lagrer than 0
        while(bccomp($i, '0') > 0) {
            //Modulo 16 and append hex char to result
            $r.= $hex[$mod = bcmod($i, '16')];
            //i = (i - mod) / 16
            $i = bcdiv(bcsub($i, $mod), '16');
        }
    //Reverse result and return
    return strrev($r);
}

var_dump(dechex32(12345678900));
/*string(9) "2dfdc1c34"*/

Didn't test thoroughly but seems to work. Use as a last resort - rough benchmarking with 100,000 iterations did show, that it's ~40 times slower than native implemetation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜