>  기사  >  백엔드 개발  >  PHP 단축링크, 단축URL, 단축URL 구현코드

PHP 단축링크, 단축URL, 단축URL 구현코드

WBOY
WBOY원래의
2016-07-25 08:57:441495검색
  1. /**
  2. * 短连接生成算法
  3. * site: bbs.it-home.org
  4. */
  5. class Short_Url {
  6. #字符表
  7. public static $charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  8. public static function short($url) {
  9. $key = "alexis";
  10. $urlhash = md5($key . $url);
  11. $len = strlen($urlhash);
  12. #将加密后的串分成4段,每段4字节,对每段进行计算,一共可以生成四组短连接
  13. for ($i = 0; $i < 4; $i++) {
  14. $urlhash_piece = substr($urlhash, $i * $len / 4, $len / 4);
  15. #将分段的位与0x3fffffff做位与,0x3fffffff表示二进制数的30个1,即30位以后的加密串都归零
  16. $hex = hexdec($urlhash_piece) & 0x3fffffff; #此处需要用到hexdec()将16进制字符串转为10进制数值型,否则运算会不正常
  17. $short_url = "http://t.cn/";
  18. #生成6位短连接
  19. for ($j = 0; $j < 6; $j++) {
  20. #将得到的值与0x0000003d,3d为61,即charset的坐标最大值
  21. $short_url .= self::$charset[$hex & 0x0000003d];
  22. #循环完以后将hex右移5位
  23. $hex = $hex >> 5;
  24. }
  25. $short_url_list[] = $short_url;
  26. }
  27. return $short_url_list;
  28. }
  29. }
  30. $url = "http://www.bbs.it-home.org/jb//";
  31. $short = Short_Url::short($url);
  32. print_r($short);
  33. ?>
复制代码

输出结果: Array ( [0] => http://t.cn/KyfLyH [1] => http://t.cn/bPafHS [2] => http://t.cn/H880aD [3] => http://t.cn/TmvDK0 )

生成的短url存到服务器里,做一个映射,short_url => original_url,输入短url的时候按照映射转回长url,然后访问原始url即可。

代码:

  1. Class TinyURL {
  2. static private $key = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; //可以多位 保证每位的字符在URL里面正常显示即可
  3. private function __construct() {}
  4. private function __clone(){}
  5. static public function encode($value) {
  6. $base = strlen( self::$key );
  7. $arr = array();
  8. while( $value != 0 ) {
  9. $arr[] = $value % $base;
  10. $value = floor( $value / $base );
  11. }
  12. $result = "";
  13. while( isset($arr[0]) ) $result .= substr(self::$key, array_pop($arr), 1 );
  14. return $result;
  15. }
  16. static public function decode($value) {
  17. $base = strlen( self::$key );
  18. $num = 0;
  19. $key = array_flip( str_split(self::$key) );
  20. $arr = str_split($value);
  21. for($len = count($arr) - 1, $i = 0; $i <= $len; $i++) {
  22. $num += pow($base, $i) * $key[$arr[$len-$i]];
  23. }
  24. return $num;
  25. }
  26. }
复制代码

调用示例:

  1. $t = 100;
  2. $time_start = microtime(true);
  3. while($t--){
  4. var_dump( TinyURL::encode(1000000) );
  5. var_dump( TinyURL::decode("4C92") );
  6. }
  7. $time_end = microtime(true);
  8. printf("[内存使用: %.2fMB]\r\n", memory_get_usage() /1024 /1024 );
  9. printf("[内存最高使用: %.2fMB]\r\n", memory_get_peak_usage() /1024 /1024) ;
  10. printf("[执行时间: %.2f毫秒]\r\n", ($time_end - $time_start) * 1000 );
复制代码

위 코드는 다음에 적합합니다. 자체 증가 ID를 갖춘 기존 관계형 데이터베이스입니다. SQL을 두 번 실행해야 합니다. 첫 번째는 자동 증가 ID를 얻고 두 번째는 ID를 기반으로 짧은 링크를 생성합니다. [또는 3번, 이 짧은 링크가 존재하는지 확인하기 위해 추가 시간이 사용됩니다. ]

또한 URL을 기반으로 해시 작업을 수행하는 알고리즘이 있습니다. 이 알고리즘의 장점은 다음과 같습니다. 1. ID가 필요하지 않으며, Key/Value 형식으로 저장 가능합니다. 2. SQL 삽입에는 하나의 명령문만 필요합니다. 3. 생성된 데이터는 개별적이며 생성 규칙을 준수할 수 없습니다.

단점: 1. 모든 해시 알고리즘은 충돌 가능성이 있습니다. 충돌이 발생하면 원본을 덮어쓰게 됩니다. [물론 판단을 위해 추가적인 논리를 추가할 수도 있습니다. ] 2. 데이터 크기는 제어하기 어렵습니다. 언제 새로운 해시 데이터 비트를 사용할 수 있는지 알 수 없지만 데이터 양이 증가하면 충돌 가능성이 점점 높아집니다. 이런 종류의 코드는 NoSQL과 같은 비관계형 데이터베이스에 적합하며, 빠른 검색과 업데이트가 가능합니다.



성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.