最近有用到将新浪微博的mid地址转换成短格式编码的方法,例如:
221110410216147026
转换后:
zF4mOFpN7A
比如新浪微博地址可以组装成这样:http://weibo.com/1642634100/5en0UftjV8H,其中数字是用户的id,后面的字符串是base62加密后的mid,因此通过组装这两个,可以得到信息的主体。
本文的代码,是由http://forum.open.weibo.com/read.php?tid=3236&uid=89934的博主的js代码改成php而来
贴下代码,运行和博主的一样,这里只是将mid转成短格式,其实逆向也很好改了:
<?php $str62keys = array( "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z","A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ); /** * 10进制值转换为62进制 * @param {String} int10 10进制值 * @return {String} 62进制值 */ function int10to62($int10) { global $str62keys; $s62 = ''; $r = 0; while ($int10 != 0) { $r = $int10 % 62; $s62 = $str62keys[$r].$s62; $int10 = floor($int10 / 62); } return $s62; } /** * * 通过mid获得短格式 * @param string $mid * @return 短格式 */ function getCodeByMid($mid){ $url = ''; for ($i = strlen($mid) - 7; $i > -7; $i -=7) //从最后往前以7字节为一组读取mid { $offset1 = $i < 0 ? 0 : $i; $offset2 = $i + 7; $num = substr($mid, $offset1,$offset2-$offset1); //mid.substring(offset1, offset2); $num = int10to62($num); $url = $num .$url; } return $url; } echo getCodeByMid('221110410216147026'); ?>
为了方便,这里把那位博主的js代码也贴在这里,大家可以做一个对照:
/** * 新浪微博mid与url互转实用工具 * 作者: XiNGRZ (http://weibo.com/xingrz) */ var WeiboUtility = {}; /** * 62进制字典 */ WeiboUtility.str62keys = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ]; /** * 62进制值转换为10进制 * @param {String} str62 62进制值 * @return {String} 10进制值 */ WeiboUtility.str62to10 = function(str62) { var i10 = 0; for (var i = 0; i < str62.length; i++) { var n = str62.length - i - 1; var s = str62[i]; i10 += this.str62keys.indexOf(s) * Math.pow(62, n); } return i10; }; /** * 10进制值转换为62进制 * @param {String} int10 10进制值 * @return {String} 62进制值 */ WeiboUtility.int10to62 = function(int10) { var s62 = ''; var r = 0; while (int10 != 0) { r = int10 % 62; s62 = this.str62keys[r] + s62; int10 = Math.floor(int10 / 62); } return s62; }; /** * URL字符转换为mid * @param {String} url 微博URL字符,如 "wr4mOFqpbO" * @return {String} 微博mid,如 "201110410216293360" */ WeiboUtility.url2mid = function(url) { var mid = ''; for (var i = url.length - 4; i > -4; i = i - 4) //从最后往前以4字节为一组读取URL字符 { var offset1 = i < 0 ? 0 : i; var offset2 = i + 4; var str = url.substring(offset1, offset2); str = this.str62to10(str); if (offset1 > 0) //若不是第一组,则不足7位补0 { while (str.length < 7) { str = '0' + str; } } mid = str + mid; } return mid; }; /** * mid转换为URL字符 * @param {String} mid 微博mid,如 "201110410216293360" * @return {String} 微博URL字符,如 "wr4mOFqpbO" */ WeiboUtility.mid2url = function(mid) { if (typeof(mid) != 'string') return false; //mid数值较大,必须为字符串! var url = ''; for (var i = mid.length - 7; i > -7; i = i - 7) //从最后往前以7字节为一组读取mid { var offset1 = i < 0 ? 0 : i; var offset2 = i + 7; var num = mid.substring(offset1, offset2); num = this.int10to62(num); url = num + url; } return url; };
echo getCodeByMid(‘0’);
输出空字符,这里应该返回字符串0,对吧?
hack一下getCodeByMid函数,for循环体内最后一行加上if ($url === ”) return 0;
if ($url === ”) return ‘0’;
3700397698838362 这个的话就会有问题,正确解析出来的应该是B0alrB5ge 但是用您这个算法解析出来是BalrB5ge 少了一个0
是的。