62进制按这个排列: $dict = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
请高手写个函数 输入16进制,输出62进制,不要用高精度数学函数,服务器禁用了.php16进制62进制进制转换

解决方案 »

  1.   

    <?php
    $dict = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    //$num=3844;//intval($_GET['hex'],16);

    for($test=0;$test<3844;$test++){
    $num=$test;
    $index=0;
    do{
    $cur=$num%62;
    $output[$index]=$dict[$cur];
    //echo $output[$index].' ';
    $num=floor($num/62);
    $index++;
    //echo $cur.' ';
    }while($num);
    $output[$index]='!';
    $index--;
    $aide=0;
    while($index>$aide){
    $tmp=$output[$index];
    $output[$index]=$output[$aide];
    $output[$aide]=$tmp;
    $aide++;
    $index--;
    }
    $index=0;
    while($output[$index]<>'!'){
    echo $output[$index];
    $index++;
    }
    if(($test+1)%62==0)
    echo '<br />';
    }
    ?>我PHP不怎么熟,很多地方都是从C语言的角度去思考的,所以有的地方很别扭。另外我不能保证我写的这个东西没错误,PHP很多地方都很模糊。那个for是为了看看有没有错误的,3位以下的62进制数好像是没什么问题。
      

  2.   

    还有超出整数的取值范围就会出问题了。如果想实现更大的数的转换,看看这个:
    http://www.php.net/manual/en/book.bc.php
      

  3.   

    本帖最后由 xuzuning 于 2013-05-01 19:14:06 编辑
      

  4.   

    这个可能不需要BCMath,不过我没试:
    http://phpseclib.bantux.org/code_coverage/220/PHP-5.2/Math_BigInteger.php.html
      

  5.   


    不会的 ,那个16进制数 其实就是一个md5 加密后的结果
    MD5那么多位怎么可能不超过整形的表示范围?
    上面那个链接里的代码好像不能下载,这个可以下载:
    http://pear.php.net/package/Math_BigInteger/download
      

  6.   

    那么为什么要是 62 进制呢?64 进制不好吗?
    因为你不过只是想紧缩一下 MD5 的结果
    测试代码
    $c = md5('ffff');
    echo $c, PHP_EOL;echo $r = convert($c, 64), PHP_EOL;
    echo convert($r, -64);function convert($s, $to=64) {
      $dict = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@=';
      $res = '';
      $b = '';
      if($to > 0) {
        $to = ceil(log($to, 2));//调整到2的k次方
        for($i=0; $i<strlen($s); $i++) $b .= sprintf('%04b', hexdec($s{$i}));
        while(strlen($b) >= $to) {
          $res = $dict{bindec(substr($b, -$to))} . $res;
          $b = substr($b, 0, -$to);
        }
        $res = $dict{bindec($b)} . $res;
        return $res;
      }
      $to = ceil(log(-$to, 2));
      for($i=0; $i<strlen($s); $i++) $b .= sprintf("%0{$to}b", strpos($dict, $s{$i}));
      while(strlen($b) > 4) {
        $res = $dict{bindec(substr($b, -4))} . $res;
        $b = substr($b, 0, -4);
      }
      if(bindec($b)) $res = $dict{bindec($b)} . $res;
      return $res;
    }
    ece926d8c0356205276a45266d361161
    3IWiroM3ly1itGhipJdx5x
    ece926d8c0356205276a45266d361161
      

  7.   

    那么为什么要是 62 进制呢?64 进制不好吗?
    因为你不过只是想紧缩一下 MD5 的结果
    测试代码
    $c = md5('ffff');
    echo $c, PHP_EOL;echo $r = convert($c, 64), PHP_EOL;
    echo convert($r, -64);function convert($s, $to=64) {
      $dict = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@=';
      $res = '';
      $b = '';
      if($to > 0) {
        $to = ceil(log($to, 2));//调整到2的k次方
        for($i=0; $i<strlen($s); $i++) $b .= sprintf('%04b', hexdec($s{$i}));
        while(strlen($b) >= $to) {
          $res = $dict{bindec(substr($b, -$to))} . $res;
          $b = substr($b, 0, -$to);
        }
        $res = $dict{bindec($b)} . $res;
        return $res;
      }
      $to = ceil(log(-$to, 2));
      for($i=0; $i<strlen($s); $i++) $b .= sprintf("%0{$to}b", strpos($dict, $s{$i}));
      while(strlen($b) > 4) {
        $res = $dict{bindec(substr($b, -4))} . $res;
        $b = substr($b, 0, -4);
      }
      if(bindec($b)) $res = $dict{bindec($b)} . $res;
      return $res;
    }
    ece926d8c0356205276a45266d361161
    3IWiroM3ly1itGhipJdx5x
    ece926d8c0356205276a45266d361161

    其实我是想用16位 md5  做成4位 64进制的短网址,尽管有很大几率些碰撞