代码之家  ›  专栏  ›  技术社区  ›  Stefan Gehrig

将字节流转换为数字数据类型

  •  1
  • Stefan Gehrig  · 技术社区  · 17 年前

    假设我有一个字节流,其中我知道64位值(64位随机数)的位置。字节顺序是小Endian。由于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 回复  |  直到 14 年前
        1
  •  6
  •   Community Mohan Dere    8 年前

    Zend_Crypt_Math_BigInteger_Bcmath Zend_Crypt_Math_BigInteger_Gmp 其处理该问题:

    这基本上是由发布的解决方案 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(Litte Endian)

    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;
    }
    

    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);
    }
    
        2
  •  1
  •   Chad Birch    17 年前

    这似乎是一个彻底的黑客攻击,但它应该能完成这项工作,假设你有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);
    }
    
        3
  •  1
  •   Anon    15 年前

    迟到了两年,但如果有人还在乎的话:

        4
  •  0
  •   user39113    17 年前

    我知道这不是问题的答案,但看看 the BC Math functions 处理大数字。

    推荐文章