琢磨着开发一款微博应用吧, 用户至上的原则, 决定让用户传递微博地址过来, 我去分析微博的信息. 然后, 发现微博的地址是/uid/str这样的. 其中str是一串英文数字混合的不算长的字符串. 开始我还不知道这个就是mid. 因为我看接口返回数据的范例中的mid是很长一串数字… 接下来我就开始了62进制转10进制的编程之旅了.
进制转换,这个我就不赘述原理了, 请自行搜索. 简单举例吧. 比如十六进制所有字符为 0123456789abcdef, 当然,是按照小的在前边, 大的在后边排列的. 那么十六进制的a转换成十进制就是10. 直接看的话, 就是从0开始数,第10个是a. 那么十六进制的1a转换成十进制怎么看呢. 先看a,是10. 然后看1. 因为1已经是进位一次后得出来的了,而逢十六才进位一次. 所以,这个1要乘以16. 那么16+10 = 26.也就是1a的十进制结果了. (说不赘述,还墨迹了一下下)
然后, 懂了十六进制与十进制互转. 也就懂了其他进制与十进制的互转了. 比如我们常常用到的0-9a-zA-Z.这一共是62个字符. 也就可以创造出62进制. 这在短域名方面应用的相当恰当. 微博也换成62进制了, 主要原因应该是减少网络传输吧.
上代码:
function s2n($str){ $x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $number = 0; for ($cnt = strlen($str), $i = $cnt - 1, $p = 0; $i >= 0; --$i, ++$p) { $number += strpos($x, $str[$i]) * pow(62, $p); } return $number; } function n2s($number){ $x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; $str = ''; do { $p = $number > PHP_INT_MAX ? intval(bcmod($number, 62)) : intval($number % 62); $str = $x[$p] . $str; if (($number = $number / 62) < 62){ $str = $x[intval($number)] . $str; break; } }while (true); return $str; } ini_set('precision', 30); //浮点数显示精度 读鸟哥博客发现的 $str = 'zbRaBuwmp'; $number = s2n($str); echo $number, PHP_EOL; echo n2s($number);
需要注意的地方就是, 如果你的进制数大于你的系统位数. 那么就悲剧了. 所以, 采用bcmath相关的函数. 具体怎么悲剧的. 我赶脚程序猿们应该自己试一试, 结果会让你记的更深刻.