php5 包在 x84_64 环境下损坏

发布于 2024-11-03 16:32:17 字数 163 浏览 0 评论 0原文

 pack('H*', dechex(12345678900)) /* 在 32 位上 */  
!= pack('H*', dechex(12345678900)) /* 在 64 位上 */

为什么 ?

   pack('H*', dechex(12345678900)) /* on 32bit */  
!= pack('H*', dechex(12345678900)) /* on 64bit */

why ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

断念 2024-11-10 16:32:17

我不知道如何解决它,但我想我知道为什么会发生这种情况。这里没有错误 - 直接从手册 http://php.net/manual/en/ function.dechex.php

可转换的最大数字为十进制 4294967295,结果为“ffffffff”

我不知道 php“内部”究竟发生了什么,但您可能会导致 32 位无符号整数溢出(12,345,678,900 > 4,294,967,295)。由于在 64 位上此限制应为 18,446,744,073,709,551,615,dechex 返回“正确”值(32 与 64 位差异似乎没有记录,我可能是错的,因为我没有用于测试的 64 位系统)。

//编辑:

作为最后的手段,你可以使用 GMP 扩展来制作你自己的hecdex 函数适用于 32 位系统,但这会产生大量的开销。可能将是现代编程中已知的最慢的实现之一。

//Edit2:

使用 BCMath 编写了一个函数,我在 Windows 上此刻,正在努力寻找 GMP 的正确 dll。

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"*/

没有彻底测试,但似乎有效。作为最后的手段使用 - 100,000 次迭代的粗略基准测试确实表明,它比本机实现慢约 40 倍。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文