1

64ビット値(64ビットナンス)の場所がわかっているバイトストリームがあるとします。バイトオーダーはリトルエンディアンです。PHPの整数データ型は32ビットに制限されているので(少なくとも32ビットオペレーティングシステムでは)、バイトシーケンスをPHPの数値表現に変換するにはどうすればよいですか(フロートで十分だと思います)。

$serverChallenge = substr($bytes, 24, 8);
// $serverChallenge now contains the byte-sequence 
// of which I know that it's a 64-bit value
4

4 に答える 4

6

この問題を処理するZend_Crypt_Math_BigInteger_Bcmathとのコードを調べただけです。Zend_Crypt_Math_BigInteger_Gmp

BCmath (ビッグエンディアン) の使用

これは基本的にChad Birchによって投稿されたソリューションです。

public static function bc_binaryToInteger($operand)
{
    $result = '0';
    while (strlen($operand)) {
        $ord = ord(substr($operand, 0, 1));
        $result = bcadd(bcmul($result, 256), $ord);
        $operand = substr($operand, 1);
    }
    return $result;
}

GMP (ビッグエンディアン) の使用

同じアルゴリズム - 関数名が異なるだけです。

public static function gmp_binaryToInteger($operand)
{
    $result = '0';
    while (strlen($operand)) {
        $ord = ord(substr($operand, 0, 1));
        $result = gmp_add(gmp_mul($result, 256), $ord);
        $operand = substr($operand, 1);
    }
    return gmp_strval($result);
}

リテ エンディアンのバイト順を使用するようにアルゴリズムを変更するのは非常に簡単です。バイナリ データを最初から最後まで読み取るだけです。

BCmath (リテエンディアン) の使用

public static function bc_binaryToInteger($operand)
{
    // Just reverse the binray data
    $operand = strrev($operand);
    $result = '0';
    while (strlen($operand)) {
        $ord = ord(substr($operand, 0, 1));
        $result = bcadd(bcmul($result, 256), $ord);
        $operand = substr($operand, 1);
    }
    return $result;
}

GMP (リテエンディアン) の使用

public static function gmp_binaryToInteger($operand)
{
    // Just reverse the binray data
    $operand = strrev($operand);
    $result = '0';
    while (strlen($operand)) {
        $ord = ord(substr($operand, 0, 1));
        $result = gmp_add(gmp_mul($result, 256), $ord);
        $operand = substr($operand, 1);
    }
    return gmp_strval($result);
}
于 2009-04-08T07:10:19.970 に答える
1

パーティーに 2 年遅れましたが、それでも気にする人がいる場合: unpack は組み込みの方法であり、32 ビット int のカップル、または double として unpack できます。

于 2011-05-15T00:27:13.773 に答える
1

これは完全なハックのように見えますが、daemonmoi が推奨する BC Math 関数を持っていると仮定すると、仕事をするはずです:

$result = "0";
for ($i = strlen($serverChallenge) - 1; $i >= 0; $i--)
{
    $result = bcmul($result, 256); // shift result

    $nextByte = (string)(ord($serverChallenge[$i]));
    $result = bcadd($result, $nextByte);
}
于 2009-04-07T15:24:36.077 に答える
0

これが質問に対する答えではないことはわかっていますが、大きな数を処理する BC Math 関数を調べてください。

于 2009-04-07T14:46:14.250 に答える