-
- /**
- * 短连接生成算法
- * site: bbs.it-home.org
- */
- class Short_Url {
- #字符表
- public static $charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
- public static function short($url) {
- $key = "alexis";
- $urlhash = md5($key . $url);
- $len = strlen($urlhash);
-
- #将加密后的串分成4段,每段4字节,对每段进行计算,一共可以生成四组短连接
- for ($i = 0; $i < 4; $i++) {
- $urlhash_piece = substr($urlhash, $i * $len / 4, $len / 4);
- #将分段的位与0x3fffffff做位与,0x3fffffff表示二进制数的30个1,即30位以后的加密串都归零
- $hex = hexdec($urlhash_piece) & 0x3fffffff; #此处需要用到hexdec()将16进制字符串转为10进制数值型,否则运算会不正常
-
- $short_url = "http://t.cn/";
- #生成6位短连接
- for ($j = 0; $j < 6; $j++) {
- #将得到的值与0x0000003d,3d为61,即charset的坐标最大值
- $short_url .= self::$charset[$hex & 0x0000003d];
- #循环完以后将hex右移5位
- $hex = $hex >> 5;
- }
-
- $short_url_list[] = $short_url;
- }
-
- return $short_url_list;
- }
- }
-
- $url = "http://www.bbs.it-home.org/jb//";
- $short = Short_Url::short($url);
- print_r($short);
- ?>
复制代码
输出结果:
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即可。
代码:
-
-
- Class TinyURL {
- static private $key = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; //可以多位 保证每位的字符在URL里面正常显示即可
- private function __construct() {}
- private function __clone(){}
-
- static public function encode($value) {
- $base = strlen( self::$key );
- $arr = array();
- while( $value != 0 ) {
- $arr[] = $value % $base;
- $value = floor( $value / $base );
- }
- $result = "";
- while( isset($arr[0]) ) $result .= substr(self::$key, array_pop($arr), 1 );
- return $result;
- }
-
- static public function decode($value) {
- $base = strlen( self::$key );
- $num = 0;
- $key = array_flip( str_split(self::$key) );
- $arr = str_split($value);
- for($len = count($arr) - 1, $i = 0; $i <= $len; $i++) {
- $num += pow($base, $i) * $key[$arr[$len-$i]];
- }
- return $num;
- }
- }
复制代码
调用示例:
-
-
- $t = 100;
- $time_start = microtime(true);
- while($t--){
- var_dump( TinyURL::encode(1000000) );
- var_dump( TinyURL::decode("4C92") );
- }
- $time_end = microtime(true);
- printf("[内存使用: %.2fMB]\r\n", memory_get_usage() /1024 /1024 );
- printf("[内存最高使用: %.2fMB]\r\n", memory_get_peak_usage() /1024 /1024) ;
- printf("[执行时间: %.2f毫秒]\r\n", ($time_end - $time_start) * 1000 );
复制代码
上記のコードは次の用途に適しています。
自己増加 ID を持つ従来のリレーショナル データベース。
SQL は 2 回実行する必要があります。1 回目は自動インクリメント ID を取得し、2 回目は ID に基づいて短いリンクを生成します。 [または 3 回、この短いリンクが存在するかどうかを判断するために追加の時間が使用されます。 ]
さらに、URL に基づいてハッシュ操作を実行する別のアルゴリズムもあります。このアルゴリズムの利点は次のとおりです。
1. ID は必要なく、Key/Value の形式で保存できます。
2. SQL の挿入に必要なステートメントは 1 つだけです。
3. 生成されたデータは離散的であり、生成規則が守られない。
短所:
1. すべてのハッシュ アルゴリズムには競合が発生する可能性があります。競合が発生すると、元のアルゴリズムが上書きされます。 [もちろん、追加のロジックを追加して判断することもできます。 】
2. データ サイズの制御は困難ですが、新しいハッシュ データ ビットをいつ使用できるかはわかりませんが、データ量が増加するにつれて、競合の可能性がますます高くなります。
この種のコードは、NoSQL などの非リレーショナル データベースに適しており、迅速に検索し、迅速に更新できます。
|