新浪mid与id互转

来源:互联网 发布:蜘蛛软件 爬虫软件 编辑:程序博客网 时间:2024/05/22 06:19

前言:

    工作需要,顺带研究下,参考资料  新浪微博地址url字符与mid的相互转换算法及原理 由于原文代码看起来有点挫,所以决定把他代码拿过来改改,自己写一个。

    新浪微博链接格式为:http://weibo.com/用户id/mid?其它参数,例如 http://weibo.com/1646512101/A3m18DfFN?mod=weibotime 。而新浪的api有的接口是使用id作为参数,而我们获取的往往是一个url,也就是只能获取mid,所以需要一步转换。显然这一步转换只是个算法问题,新浪也是提供这样的api的,不过api接口调用频率有严格的限制,要是能在本地直接算出来不是更好?其实我觉得新浪把这算法公开不就得了,还省了很多流量。

算法原理:

    目的是把 类似 'A3m18DfFN' 这样的串与 '3607996229355043' 这样的纯数字串互相转换。短的串看起来爽一点,而纯数字串在存储方面可能好些。

     从纯数字到字母和数字组合的转换非常简单,这里用了62个字符做字典:"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

    比如说有个纯数字串 “12153”,那转换结果就是"3a1"  ( 12153 =  3 * 62^2 + 10*62^1 + 1*62^0 ),转换回来也是一样的道理。

    而新浪的转换是把数字从末尾往前分成每7个数字一组进行转换,转换完再把结果合并起来。暂时还不清楚为什么要分组,直接转不就得了(有知道的告诉一声,谢谢)。

    而转换回来把字母数字组合从末尾往前每四个一组进行转换,转换完再把结果合并起来。下面直接看代码吧:

class Str2numeric{      public static $str62 = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";        public static function id2mid($id)      {          $result = '';          $len   = strlen($id);          $start = $len-7;          $end   = $len;          for($i=$len-7;$i>-7;$i-=7){              $start  = $i<0?0:$i;              $end    = $i + 7;              $result = self::int10to62(substr($id,$start,$end-$start)) . $result;          }          return $result;      }      public static function int10to62($num)      {          $result = '';          while($num){              $result = self::$str62[$num%62] . $result;              $num = floor($num/62);          }          return $result;      }        public static function mid2id($mid)      {          $result = '';          $len = strlen($mid);          for($i=$len-4;$i>-4;$i-=4){              $start  = $i<0?0:$i;              $end    = $i + 4;              $result = self::str62to10(substr($mid,$start,$end-$start)) . $result;          }          return ltrim($result,0);      }      public static function str62to10($str62)      {          $num = 0;          $len = strlen($str62);          $power = 1;          for($i=$len-1;$i>=0;$i--){              $num += strpos(self::$str62,$str62[$i]) * $power;              $power *= 62;          }          $num = str_pad($num,7,"0",STR_PAD_LEFT);          return $num;      }  }    echo Str2numeric::id2mid('3605852122436718'),"\n",Str2numeric::mid2id('A2seUadTU'),"\n";  echo Str2numeric::id2mid('3607996229355043'),"\n",Str2numeric::mid2id('A3m18DfFN'),"\n";