Baz keyfi büyüklükte sayılar (PHP) dönüşümü

3 Cevap php

Ben PHPs paketi fonksiyonunun çıkışı gibi uzun bir "ikili bir dize" var.

How can I convert this value to base62 (0-9a-zA-Z)? The built in maths functions overflow with such long inputs, and BCmath doesn't have a base_convert function, or anything that specific. I would also need a matching "pack base62" function.

3 Cevap

Ben bu soruların arkasında bir yanlış anlaşılma olduğunu düşünüyorum. Taban dönüşüm ve kodlama / kod çözme vardır different. Base64_encode çıkışı (...) not çok base64 sayıdır. Bu kompresyon fonksiyonuna karşılık, ayrık base64 değerlerinin bir dizisi.

base64_encode(1234) = "MTIzNA=="
base64_convert(1234) = "TS" //if the base64_convert function existed

base64 encoding 3 byte (24 bit) gruba kadar girdi kırılır, sonra gelen base64 karakteri (değerleri (hedef baz 2 ^ 6 = 64) 6 bit her bir alt segmenti dönüştürür "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789 + /", burada A = 0, / = 63) bulunmaktadır.

(ASCII) "1234" binary 00110001 00110010 00110011 00110100 çünkü bizim örneğimizde, "1234", MTIZNA == olur. Bu 001.100 içine bozulur (M) 010011 (T) 001000 (I) 110011 (z) 001101 (N) 00. Son grup tam olmadığından, bu 0 ve değeri 000.000 (A) ile doldurulur alır. "123" ve "4": Her şey 3 giriş karakter gruplar tarafından yapılır çünkü, 2 grup var. Son grup, 3 karakter uzun yapmak = 's ile şişirilir, böylece bütün çıkışı "MTIZNA ==" hale gelir.

converting to base64, diğer taraftan, tek bir tam sayı değeri alır ve tek bir base64 değere dönüştürür. Yukarıdaki gibi base64 değerlerin aynı dizeyi kullanın eğer bizim Örneğin, 1234 (ondalık), "TS" (base64) olduğunu. Geriye Çalışma ve soldan sağa: = 19 T (sütun 1) = 18 S (sütun 0), yani (19 * 64 ^ 1) + (18 * 64 ^ 0) = 1234 = 19 * 64 + 18 (ondalık).

Eğer gerçekten base62 var yoksa, neden gitmek değil:

base64_encode()
base64_decode()

Sadece eklenen diğer karakterleri "+" ve "=", ve diğer birçok dilde fonksiyonları ile ikili dizeleri paketi ve açmak için bir çok iyi bilinen bir yöntem.

, Burada bir fonksiyon base_conv() Bu tamamen keyfi üsleri arasında dönüştürebilirsiniz, dizeleri diziler olarak ifade edilir Her dizi eleman da (bu karışıklığı önlemek için sizin sorumluluğunuzdadır) çoklu karakter değerlerini sağlayarak, bu temel bir tek "rakamı" temsil eder.

function base_conv($val, &$baseTo, &$baseFrom)
    {
    return base_arr_to_str(base_conv_arr(base_str_to_arr((string) $val, $baseFrom), count($baseTo), count($baseFrom)), $baseTo);
    }

function base_conv_arr($val, $baseToDigits, $baseFromDigits)
    {
    $valCount = count($val);
    $result = array();
    do
        {
        $divide = 0;
        $newlen = 0;
        for ($i = 0; $i < $valCount; ++$i)
            {
            $divide = $divide * $baseFromDigits + $val[$i];
            if ($divide >= $baseToDigits)
                {
                $val[$newlen ++] = (int) ($divide / $baseToDigits);
                $divide = $divide % $baseToDigits;
                }
            else if ($newlen > 0)
                {
                $val[$newlen ++] = 0;
                }
            }
        $valCount = $newlen;
        array_unshift($result, $divide);
        }
        while ($newlen != 0);
    return $result;
    }

function base_arr_to_str($arr, &$base)
    {
    $str = '';
    foreach ($arr as $digit)
        {
        $str .= $base[$digit];
        }
    return $str;
    }

function base_str_to_arr($str, &$base)
    {
    $arr = array();
    while ($str === '0' || !empty($str))
        {
        foreach ($base as $index => $digit)
            {
            if (mb_substr($str, 0, $digitLen = mb_strlen($digit)) === $digit)
                {
                $arr[] = $index;
                $str = mb_substr($str, $digitLen);
                continue 2;
                }
            }
        throw new Exception();
        }
    return $arr;
    }

Örnekler:

$baseDec = str_split('0123456789');
$baseHex = str_split('0123456789abcdef');

echo base_conv(255, $baseHex, $baseDec); // ff
echo base_conv('ff', $baseDec, $baseHex); // 255

// multi-character base:
$baseHelloworld = array('hello ', 'world ');
echo base_conv(37, $baseHelloworld, $baseDec); // world hello hello world hello world 
echo base_conv('world hello hello world hello world ', $baseDec, $baseHelloworld); // 37

// ambiguous base:
// don't do this! base_str_to_arr() won't know how to decode e.g. '11111'
// (well it does, but the result might not be what you'd expect;
// It matches digits sequentially so '11111' would be array(0, 0, 1)
// here (matched as '11', '11', '1' since they come first in the array))
$baseAmbiguous = array('11', '1', '111');