10进制和64进制互转

以前写过16进制和64进制的转换函数,今天做下载页的短连接,突然想到可以吧id转换为64进制,让地址看起来更短,下面是代码,分享给大家。性能测试,1000次计算互转计算,4位64进制数( aaaa: 2663050),用时100毫秒左右,平均一次转换用时50微秒左右。
 
 
<?php
class jinzhi {
    const KeyCode = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$';
   
    /**
     * 将64进制的数字字符串转为10进制的数字字符串
     * @param $m string 64进制的数字字符串
     * @param $len integer 返回字符串长度,如果长度不够用0填充,0为不填充
     * @return string
     * @author 野马
     */
    public function hex64to10( $m , $len = 0) {
        $m = ( string) $m;
        $hex2 = '';
        $Code = self :: KeyCode;
        for( $i = 0 , $l = strlen( $Code); $i < $l; $i ++) {
            $KeyCode [] = $Code [ $i ];
        }
        $KeyCode = array_flip( $KeyCode);
       
        for( $i = 0 , $l = strlen( $m); $i < $l; $i ++) {
            $one = $m [ $i ];
            $hex2 .= str_pad( decbin( $KeyCode [ $one ]), 6 , '0' , STR_PAD_LEFT);
        }
        $return = bindec( $hex2);
       
        if( $len) {
            $clen = strlen( $return);
            if( $clen >= $len) {
                return $return;
            }
            else {
                return str_pad( $return , $len , '0' , STR_PAD_LEFT);
            }
        }
        return $return;
    }
   
    /**
     * 将10进制的数字字符串转为64进制的数字字符串
     * @param $m string 10进制的数字字符串
     * @param $len integer 返回字符串长度,如果长度不够用0填充,0为不填充
     * @return string
     * @author 野马
     */
    public function hex10to64( $m , $len = 0) {
        $KeyCode = self :: KeyCode;
        $hex2 = decbin( $m);
        $hex2 = $this -> str_rsplit( $hex2 , 6);
        $hex64 = array();
        foreach( $hex2 as $one) {
            $t = bindec( $one);
            $hex64 [] = $KeyCode [ $t ];
        }
        $return = preg_replace( '/^0*/' , '' , implode( '' , $hex64));
        if( $len) {
            $clen = strlen( $return);
            if( $clen >= $len) {
                return $return;
            }
            else {
                return str_pad( $return , $len , '0' , STR_PAD_LEFT);
            }
        }
        return $return;
    }
   
    /**
     * 将16进制的数字字符串转为64进制的数字字符串
     * @param $m string 16进制的数字字符串
     * @param $len integer 返回字符串长度,如果长度不够用0填充,0为不填充
     * @return string
     * @author 野马
     */
    protected function hex16to64( $m , $len = 0) {
        $KeyCode = self :: KeyCode;
        $hex2 = array();
        for( $i = 0 , $j = strlen( $m); $i < $j; ++ $i) {
            $hex2 [] = str_pad( base_convert( $m [ $i ], 16 , 2 ), 4 , '0' , STR_PAD_LEFT);
        }
        $hex2 = implode( '' , $hex2);
        $hex2 = $this -> str_rsplit( $hex2 , 6);
        foreach( $hex2 as $one) {
            $hex64 [] = $KeyCode [ bindec( $one )];
        }
        $return = preg_replace( '/^0*/' , '' , implode( '' , $hex64));
        if( $len) {
            $clen = strlen( $return);
            if( $clen >= $len) {
                return $return;
            }
            else {
                return str_pad( $return , $len , '0' , STR_PAD_LEFT);
            }
        }
        return $return;
    }
   
    /**
     * 功能和PHP原生函数str_split接近,只是从尾部开始计数切割
     * @param $str string 需要切割的字符串
     * @param $len integer 每段字符串的长度
     * @return array
     * @author 野马
     */
    protected function str_rsplit( $str , $len = 1) {
        if( $str == null || $str == false || $str == '') return false;
        $strlen = strlen( $str);
        if( $strlen <= $len) return array( $str);
        $headlen = $strlen % $len;
        if( $headlen == 0) {
            return str_split( $str , $len);
        }
        $return = array( substr( $str , 0 , $headlen));
        return array_merge( $return , str_split( substr( $str , $headlen ), $len));
    }
}
?>



工作中发现我们平时吧加密密码、授权证书、文件指纹等等进行存储和使用的时候大部分是直接使用的md5值,md5值是一个32位长16进制整数,其实我们可以吧这个16进制数转换成64进制,实现同样的功能,缩短字符串长度(32位的16进制MD5值可以压缩为22位的64进制数)。至于缩短长度有啥用处,我想你懂得O(∩_∩)O~


01 <?php
02 echo " \r\n <br />1:" . hex16to64( '1');
03 echo " \r\n <br />2:" . hex16to64( '2');
04 echo " \r\n <br />3:" . hex16to64( '3');
05 echo " \r\n <br />4:" . hex16to64( '4');
06 echo " \r\n <br />5:" . hex16to64( '5');
07 echo " \r\n <br />6:" . hex16to64( '6');
08 echo " \r\n <br />7:" . hex16to64( '7' , 5);
09 echo " \r\n <br />8:" . hex16to64( '8');
10 echo " \r\n <br />9:" . hex16to64( '9');
11 echo " \r\n <br />a:" . hex16to64( 'a');
12 echo " \r\n <br />b:" . hex16to64( 'b');
13 echo " \r\n <br />c:" . hex16to64( 'c');
14 echo " \r\n <br />d:" . hex16to64( 'd');
15 echo " \r\n <br />e:" . hex16to64( 'e');
16 echo " \r\n <br />f:" . hex16to64( 'f');
17 echo " \r\n <br />10:" . hex16to64( '10' , 4);
18 echo " \r\n <br />fffffffffffffffffffffffffffffffe:" . hex16to64( 'fffffffffffffffffffffffffffffffe' , 22);
19 echo " \r\n <br />ffffffffffffffffffffffffffffffff:" . hex16to64( 'ffffffffffffffffffffffffffffffff' , 22);
20 echo " \r\n <br />126ede66b4c850a68d56526ae05fbd11:" . hex16to64( '126ede66b4c850a68d56526ae05fbd11' , 22);
21 echo " \r\n <br />7590ee342aa65cbb0dc40418f5474aca:" . hex16to64( '7590ee342aa65cbb0dc40418f5474aca' , 22);
22 echo " \r\n <br />";
23
24 $strarr = array();
25 $time1 = microtime( true);
26 for( $i = 0; $i < 10000; ++ $i) {
27     $str = md5( $i);
28     $strarr [] = " { $i } -> $str \r\n <br>";
29 }
30 $time2 = microtime( true);
31 $time3 = $time2 - $time1;
32
33 $time1 = microtime( true);
34 for( $i = 0; $i < 10000; ++ $i) {
35     $str = hex16to64( md5( $i ), 22);
36     $strarr [] = " { $i } -> $str \r\n <br>";
37 }
38 $time2 = microtime( true);
39 echo " \r\n <br />运行10000次用时(秒):" . ( $time2 - $time1 - $time3);
40
41 /**
42 * 将16进制的数字字符串转为64位的数字字符串
43 * @param $m string 16进制的数字字符串
44 * @param $len integer 返回字符串长度,如果长度不够用0填充,0为不填充
45 * @return string
46 * @author 野马
47 */
48 function hex16to64( $m , $len = 0) {
49     $code = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_%';
50     $hex2 = array();
51     for( $i = 0 , $j = strlen( $m); $i < $j; ++ $i) {
52         $hex2 [] = str_pad( base_convert( $m [ $i ], 16 , 2 ), 4 , '0' , STR_PAD_LEFT);
53     }
54     $hex2 = implode( '' , $hex2);
55     $hex2 = str_rsplit( $hex2 , 6);
56     foreach( $hex2 as $one) {
57         $hex64 [] = $code [ bindec( $one )];
58     }
59     $return = preg_replace( '/^0*/' , '' , implode( '' , $hex64));
60     if( $len) {
61         $clen = strlen( $return);
62         if( $clen >= $len) {
63             return $return;
64         }
65         else {
66             return str_pad( $return , $len , '0' , STR_PAD_LEFT);
67         }
68     }
69     return $return;
70 }
71 /**
72 * 功能和PHP原生函数str_split接近,只是从尾部开始计数切割
73 * @param $str string 需要切割的字符串
74 * @param $len integer 每段字符串的长度
75 * @return array
76 * @author 野马
77 */
78 function str_rsplit( $str , $len = 1) {
79     if( $str == null || $str == false || $str == '') return false;
80     $strlen = strlen( $str);
81     if( $strlen <= $len) return array( $str);
82     $headlen = $strlen % $len;
83     if( $headlen == 0) {
84         return str_split( $str , $len);
85     }
86     $return = array( substr( $str , 0 , $headlen));
87     return array_merge( $return , str_split( substr( $str , $headlen ), $len));
88 }
89 ?>

以上代码在SAE上的执行效率还算不错:

http://enshui.sinaapp.com/jinzhi64.php

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值