PHP - Nasıl base_convert için () kadar 62 dayandırmak

4 Cevap php

Ben 62 tabanına kadar tabanından 2 çalışan bir base_convert() işlevini gerekiyor ama ben kullanmak gerekir matematik eksik, ben nedeniyle PHP sınırlamaları ben BCMath faydalanmak gerektiğini biliyorum ki gayet iyi.

Fonksiyonlar like these kadar 62 başka tabanına 10 ve taban arasında bir sayı dönüştürmek, ama örneğin, base_convert() aynı işlevselliğini uygulamak istiyorum: dönüştürmek bir tek fonksiyonu arasındaki keyfi bazlar.

Ben bir function that seems to do this bulduk, ama bana biraz gereksiz ve yavaş kod sahip hissi verir ve Almanca biliyordu eğer ben yok ki, bunu biraz daha oynamak istiyorum. = (

İşte fonksiyonunun daha okunabilir versiyonu:

function bc_base_convert($value, $quellformat, $zielformat)
{
    $vorrat = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

    if (min($quellformat, $zielformat) < 2)
    {
    	trigger_error('Bad Format min: 2', E_USER_ERROR);
    }

    if (max($quellformat, $zielformat) > strlen($vorrat))
    {
    	trigger_error('Bad Format max: ' . strlen($vorrat), E_USER_ERROR);
    }

    $dezi = '0';
    $level = 0;
    $result = '';
    $value = trim(strval($value), "\r\n\t +");
    $vorzeichen = '-' === $value{0} ? '-' : '';
    $value = ltrim($value, "-0");
    $len = strlen($value);

    for ($i = 0; $i < $len; $i++)
    {
    	$wert = strpos($vorrat, $value{$len - 1 - $i});

    	if (FALSE === $wert)
    	{
    		trigger_error('Bad Char in input 1', E_USER_ERROR);
    	}

    	if ($wert >= $quellformat)
    	{
    		trigger_error('Bad Char in input 2', E_USER_ERROR);
    	}

    	$dezi = bcadd($dezi, bcmul(bcpow($quellformat, $i), $wert));
    }

    if (10 == $zielformat)
    {
    	return $vorzeichen . $dezi; // abkürzung
    }

    while (1 !== bccomp(bcpow($zielformat, $level++), $dezi));

    for ($i = $level - 2; $i >= 0; $i--)
    {
    	$factor = bcpow($zielformat, $i);
    	$zahl = bcdiv($dezi, $factor, 0);
    	$dezi = bcmod($dezi, $factor);
    	$result .= $vorrat{$zahl};
    }

    $result = empty($result) ? '0' : $result;

    return $vorzeichen . $result;
}

Herkes bana yukarıdaki işlevini açıklamak ya da bana keyfi üsleri arasında doğrudan dönüşüm sürecinde bazı ışıklar verebilir misiniz?

4 Cevap

PHP 5.3.2 itibariyle bc_math ve gmp hem de artık 62 kadar üsleri destek, böylece sadece yapabilirsiniz:

echo gmp_strval(gmp_init($mynumber, $srcbase), $destbase);

veya bc_math eşdeğeri.

I nereden aldığınızı bana sormayın lütfen, ben sadece hatırlamak onun i web üzerinde bulunan bazı örneklere dayalı ...

  function charset_base_convert ($numstring, $fromcharset, $tocharset) {
     $frombase=strlen($fromcharset);
     $tobase=strlen($tocharset);
     $chars = $fromcharset;
     $tostring = $tocharset;

     $length = strlen($numstring);
     $result = '';
     for ($i = 0; $i < $length; $i++) {
         $number[$i] = strpos($chars, $numstring{$i});
     }
     do {
         $divide = 0;
         $newlen = 0;
         for ($i = 0; $i < $length; $i++) {
             $divide = $divide * $frombase + $number[$i];
             if ($divide >= $tobase) {
                 $number[$newlen++] = (int)($divide / $tobase);
                 $divide = $divide % $tobase;
             } elseif ($newlen > 0) {
                 $number[$newlen++] = 0;
             }
         }
         $length = $newlen;
         $result = $tostring{$divide} . $result;
     }
     while ($newlen != 0);
     return $result;
  }

Herhangi bir çeviri sorunları için en kolay yaklaşım, sayısal tabanından insan dillerine, bir ara format üzerinden tercüme etmektir.

function bc_base_convert($num, $from, $to) {
    return bc_convert_to(bc_parse_num($num, $from), $to);
}

Şimdi yazmak için gereken tüm bc_convert_to ve bc_parse_num vardır. Platform sayısal tür ayıran varsa, hesabınıza bu almak gerekir. Ayrıca, bir numaralı baz sonlu bir temsil olabilir, çünkü, kayan noktalı sayılar özel dikkat gerektirir, ama başka bir (örn. 1/3 3 fakat 0.333 ... 10 0.1 ve 1/10 10 ,0001100110011 olan ... 2).

Dönüşüm nasıl çalıştığını genel bir açıklama gelince, nasıl positional base systems iş düşünün. Formun bir rakam "a n bir n-1 ... bir 1 bir 0" bir baz {[(5) }] numarası "a n bn + a n-1 bn-1 + ... + a 1 temsıl eder b1 + a 0 b0. " Dönüşüm temel olarak başka bir baz β bağlamında ifade değerlendirerek çalışır.

Burada ondalık / ikili dönüşüm için BCMath fonksiyonlarını kullanarak ilgili yazdı: http://www.exploringbinary.com/base-conversion-in-php-using-bcmath/. Kolayca farklı üsleri dönüştürmek için bu kodu değiştirebilir.

Örneğin, dönüştürme tamsayılar durumunda, rutinler dec2bin_i () ve bin2dec_i () değiştirin. Bunları yeniden adlandırın ve bir taban parametreyi ekleyin - dec2base_i gibi bir şey ($ baz $ decimal_i) ve base2dec_i ($ baz $ num_i) değişken $ tabanına kodlanmış '2 'değiştirmek, karakterler için / sayısal kalanlar dönüştürmek taban ve değişkenleri yeniden adlandırın.

Şimdi, keyfi üsleri arasında dönüştürmek için, bir ara olarak ondalık kullanmak ve bu yeni fonksiyonlar hem diyoruz. Örneğin, "123" = $ B59 ardından (', '123' '42) $ Aralık = base2dec_i arayarak dec2base_i (59, $ Aralık) 59 tabanına taban 42 sayı dönüştürmek.

(Ayrıca bir çağrıda öyle bir kombine fonksiyonunu yapabilir.)