pack('H*', dechex(12345678900)) /* on 32bit */ != pack('H*', dechex(12345678900)) /* on 64bit */
なぜ ?
修正方法はわかりませんが、なぜこれが起こっているのかはわかっていると思います。ここにバグはありません - マニュアルhttp://php.net/manual/en/function.dechex.phpからまっすぐに
変換できる最大数は 10 進数で 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拡張機能を使用して 32 ビット システム用の独自の 16 進関数を作成することもできますが、それでは大量のオーバーヘッドが発生します。おそらく、現代のプログラミングで知られている最も遅い実装の 1 つになるでしょう。
//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 倍遅いことが示されました。