(belirli karakterler sadece çalışan) tabanına 31 tabanından 10 dönüştürme

6 Cevap php

Ben tabanına 31 üssü 10 numaralar dönüştürmek istiyorum

23456789abcdefghjkmnpqrstuvwxyz: Ben sadece bu karakterleri kullanmak istiyorum

Gördüğünüz gibi, 5 karakter (ben bu gerekmez) hariçtir: 1 0 o l i

Ben şimdi var işlevi aşağıda ama tabii ki çalışmaz. 2 girişi olduğunda 4. çıktılar. tenTo31(2) 2 olmalıdır için çıkış

function tenTo31($num)
{
    $out   = "";
    $alpha = "23456789abcdefghjkmnpqrstuvwxyz";

    while($num > 30)
    {
        $r = $num % 31;
        $num = floor($num / 31) - 1;
        $out = $alpha[$r] . $out;
    }

    return $alpha[$num] . $out;
}

Herhangi bir bu işi yapmak için nasıl bir fikir?

6 Cevap

Bu ne istediğinizi de kör bir tahmin olduğunu:

$alpha = "yz23456789abcdefghjkmnpqrstuvwx";

Sen 1 ve 0 karakterleri kullanarak değil, sizin numaralandırma sisteminde ilk basamak 2 anlam 2 10 tabanına 0 eşdeğerdir. 3. 10 tabanına 1'e eşittir ve 4 üssü 10 içinde 2 eşdeğer olduğunu.

Başka bir taban dönüştürme, base_convert() için yerleşik bir işlevi var. Alfabe sabittir, ancak strtr() kendi ile bu haneyi değiştirmek için kullanabilirsiniz.

"TenTo31 için çıkış (2) 2 olması gerekir": Bir olasılık daha '2 ', üçüncü sembol yapmaktır.

function tenTo31($num) {
  static $from = "0123456789abcdefghijklmnopqrstu";
  static $to   = "yz23456789abcdefghjkmnpqrstuvwx";
  return strtr(base_convert($num, 10, 31), $from, $to);
}

for($i=0; $i<31; $i++) {
 echo $i, '=', tenTo31($i), ' | ';
 if ( 9===$i%10 ) echo "\n";
}

baskılar

0=y | 1=z | 2=2 | 3=3 | 4=4 | 5=5 | 6=6 | 7=7 | 8=8 | 9=9 | 
10=a | 11=b | 12=c | 13=d | 14=e | 15=f | 16=g | 17=h | 18=j | 19=k | 
20=m | 21=n | 22=p | 23=q | 24=r | 25=s | 26=t | 27=u | 28=v | 29=w | 
30=x |

edit: To convert the base(31) number back to decimal you first have to reverse the translation (strtr) and then call base_convert(.., 31, 10). You can combine the conversion from and to base(31) in a single function.

function convert_ten_31($num, $numIsDecimal) {
  static $default = "0123456789abcdefghijklmnopqrstu";
  static $symbols = "yz23456789abcdefghjkmnpqrstuvwx";

  if ( $numIsDecimal ) {
   return strtr(base_convert($num, 10, 31), $default, $symbols);
  }
  else {
   return base_convert(strtr($num, $symbols, $default), 31, 10);
  } 
}

// testing
for($i=0; $i<10000; $i++) {
 $x = convert_ten_31($i, true);
 $x = convert_ten_31($x, false);

 if ( $i!==(int)$x ) {
  var_dump($i, $x);
  die;
 }
}
echo 'done.';

Bu,) (, tenTo31 ()) parametre olarak semboller almak ve böylece (yerine tenTo30 biri esnek işleve sahip olan) base_convert gibi bir işlevi (yazmak kolay da tenTo32 kendinizi mümkün ....

Neden 32 tarafından modülleri alıyor? Sen% 31 ve / 31 kullanmalısınız. 10 tabanında biz 10 ile modüllerini kullanarak, bu nedenle baz 31 olmalıdır. Ama biz bu konuda unutursam, ben senin mantık doğru olduğunu düşünüyorum. 10 tabanında 2 senin "modifiye basamak" ile baz 31 eşittir 4 neden ben anlayamıyorum.

Ben öğrenme egzersiz için algoritması ile birlikte devam etmenizi öneririm yaparken, sadece işi almak gerekiyorsa base_convert kullanmayı düşünebilirsiniz.

Eşleme göre http://www.crockford.com/wrmg/base32.html gibi görünmektedir:

function symbolToEncode ($num) {
    $out   = "";
    static $alpha = "0123456789ABCDEFGHJKMNPQRSTVWXYZ*~$=U";

    while ($num >= 37) {
        $r = $num % 37;
        $num = floor ($num / 37);
        $out = $out . $alpha[$r];
    }

    return $out . $alpha[$num];
}

function decodeToEncode ($str) {
  static $from = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*~=$";
  static $to   = "0123456789ABCDEFGH1JK1MN0PQRSTUVWXYZABCDEFGH1JK1MN0PQRSTUVWXYZ*~=$";
  return strtr ($str, $from, $to);
}

Açıkça gerçek bir meydan okuma, bir encodeToSymbol () fonksiyonu yazmak için olsa. Ben gerçekten bir PHP uzmanı (? Dizeleri benim $ 'ın muhtemelen bir şekilde kaçtı gerekiyor - ipuçları) değilim, bu yüzden başkalarına bırakıyoruz.