将数字基数10转换为基数62(a-zA-Z0-9)

dyn*_*mic 27 php encoding numeric alphanumeric character-encoding

我在10号基地有一个号码.无论如何将它翻译成基地62?

例:

echo convert(12324324);
// returns Yg3 (fantasy example here)
Run Code Online (Sandbox Code Playgroud)

PHP base_convert()可以转换为36.

Ein*_*eki 38

OLD:快速而肮脏的解决方案可以是使用这样的函数:

function toChars($number) {
   $res = base_convert($number, 10,26);
   $res = strtr($res,'0123456789','qrstuvxwyz');
   return $res;
}
Run Code Online (Sandbox Code Playgroud)

基本转换将您的数字转换为数字为0-9a-p的基数,然后通过快速字符替换来消除剩余数字.

正如您所看到的,该功能很容易逆转.

function toNum($number) {
   $res = strtr($number,'qrstuvxwyz','0123456789');
   $res = base_convert($number, 26,10);
   return $res;
}
Run Code Online (Sandbox Code Playgroud)

顺便问一下,你会用这个函数做什么?


编辑:

基于问题更改和@jnpcl答案,这里有一组函数,它们在不使用pow和log的情况下执行基本转换(它们花费一半的时间来完成测试).

这些函数仅适用于整数值.

function toBase($num, $b=62) {
  $base='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  $r = $num  % $b ;
  $res = $base[$r];
  $q = floor($num/$b);
  while ($q) {
    $r = $q % $b;
    $q =floor($q/$b);
    $res = $base[$r].$res;
  }
  return $res;
}

function to10( $num, $b=62) {
  $base='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  $limit = strlen($num);
  $res=strpos($base,$num[0]);
  for($i=1;$i<$limit;$i++) {
    $res = $b * $res + strpos($base,$num[$i]);
  }
  return $res;
}
Run Code Online (Sandbox Code Playgroud)

考试:

for ($i = 0; $i<1000000; $i++) {
  $x =  toBase($i);
  $y =  to10($x);
  if ($i-$y)
    echo "\n$i -> $x -> $y";
}
Run Code Online (Sandbox Code Playgroud)

  • 这种"快速而肮脏"的解决方案并不能满足要求,也不可逆转.问题是在Base 62中编码. (3认同)
  • 是的,工作正常:http://codepad.org/Lj9qRd2n(我删除了`if($ i- $ y)`check) (2认同)
  • 这些函数适用于高于2147483648的数字 (2认同)

ins*_* me 9

一个不使用pownor的更简单(并且可能更快)的实现log

function base62($num) {
  $index = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  $res = '';
  do {
    $res = $index[$num % 62] . $res;
    $num = intval($num / 62);
  } while ($num);
  return $res;
}
Run Code Online (Sandbox Code Playgroud)


dru*_*dge 7

http://us3.php.net/manual/en/function.base-convert.php#52450

<?php
// Decimal > Custom
function dec2any( $num, $base=62, $index=false ) {
    if (! $base ) {
        $base = strlen( $index );
    } else if (! $index ) {
        $index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ,0 ,$base );
    }
    $out = "";


    // this fix partially breaks when $num=0, but fixes the $num=238328 bug
    // also seems to break (adds a leading zero) at $num=226981 through $num=238327 *shrug*
    // for ( $t = floor( log10( $num ) / log10( $base - 1 ) ); $t >= 0; $t-- ) {

    // original code:
    for ( $t = floor( log10( $num ) / log10( $base ) ); $t >= 0; $t-- ) {
        $a = floor( $num / pow( $base, $t ) );
        $out = $out . substr( $index, $a, 1 );
        $num = $num - ( $a * pow( $base, $t ) );
    }
    return $out;
}
?>
Run Code Online (Sandbox Code Playgroud)

参数:

$num - 你的十进制整数

$base- 您希望转换的基数$num(如果您提供则保留0 $index或如果您使用默认值则省略(62))

$index - 如果你希望使用的数字(0-1A-ZA-Z)的默认列表,省略此选项,否则提供的字符串(例如:"zyxwvu")

<?php
// Custom > Decimal
function any2dec( $num, $base=62, $index=false ) {
    if (! $base ) {
        $base = strlen( $index );
    } else if (! $index ) {
        $index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, $base );
    }
    $out = 0;
    $len = strlen( $num ) - 1;
    for ( $t = 0; $t <= $len; $t++ ) {
        $out = $out + strpos( $index, substr( $num, $t, 1 ) ) * pow( $base, $len - $t );
    }
    return $out;
}
?>
Run Code Online (Sandbox Code Playgroud)

参数:

$num - 基于自定义的数字(字符串)(例如:"11011101")

$base- $num编码的基数(如果您提供则保留0 $index或如果您使用默认值则省略(62))

$index - 如果您希望使用默认的数字列表(0-1a-zA-Z),请省略此选项,否则提供一个字符串(例如:"abcdef")