Sayısal veri tipi içine bayt akışı dönüştürme

3 Cevap php

Diyelim ki ben bir 64-bit değerinin konumunu (64-bit Nonce) bildiğiniz bir bayt akışı var diyelim. Bayt sırası Little-Endian olduğunu. PHP'nin tamsayı veri türü nasıl bir PHP sayısal gösterimi içine bayt dizisi dönüştürmek olacaktır (en az 32-bit işletim sistemlerinde) 32-bit ile sınırlıdır gibi (şamandıra sanırım yeterli olacaktır)?

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

3 Cevap

Sadece Zend_Crypt_Math_BigInteger_Bcmath ve Zend_Crypt_Math_BigInteger_Gmp bu sorunu ele aldığı için kod baktı:

Using BCmath (Big-Endian)

Bu aslında Chad Birch tarafından yayınlanmıştır çözümdür.

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

Using GMP (Big-Endian)

Aynı algorithem - sadece farklı fonksiyon isimleri.

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

Litte-Endian bayt-sipariş kullanmak algorithem değiştirilmesi oldukça basittir: sadece başlatmak için ucundan ikili veri okumak:

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

Using GMP (Litte-Endian)

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

Bu toplam kesmek gibi görünüyor, ancak bu önerilen daemonmoi BC Math işlevlere sahip varsayarak, işi yapmalıdır:

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

Ben bu soruya oldukça cevap değil biliyorum, ama the BC Math functions büyük sayılar işlemek için check out.