近來微博很火,因為字數的限制,出現了很多網址縮短這種服務,比如sina 自己用了自家的sinaurl.cn,想到自己曾經也注冊了一個很短的域名k6.hk很久 了,一直閒著,不知道干嘛用,突然想到可以用來做網址縮短,還不錯。說干就 干,一會就寫好了。比如我的博客地址就可以縮短成:http://k6.hk/u
程序的設計很簡單,下面說下原理,
數據庫只有兩個字段seq(自增長數字)和url(數字的url地址,建立索引)。
用戶輸入一個url地址,查詢表是否包含此url,如果存在,則返回seq的數字 ,
如果不存在,則插入數據庫,得到一個新增加的自增seq數字,為了縮短數字 占用的字符數,我們可以把abc等字母的大小寫用上。這樣10個數字,26個小寫 字母,26個大小字母就組成了一個62進制了。比如數字10000000000(100億)轉換 後就是aUKYOA,只有6位了,這樣就能縮短很多的網址了。
下面是php的進制轉換代碼,來源於php手冊(簡單吧),當然其他語言實現也是很簡單的,
<?php
//十進制轉到其他制
function dec2any( $num, $base=62, $index=false ) {
if (! $base ) {
$base = strlen( $index );
} else if (! $index ) {
$index = substr ( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" , 0 ,$base );
}
$out = "";
for ( $t = floor( log10( $num ) / log10( $base ) ); $t >= 0; $t-- ) {
$a = floor( $num / pow( $base, $t ) );
$out = $out . substr( $index, $a, 1 );
$num = $num - ( $a * pow( $base, $t ) );
}
return $out;
}
function any2dec( $num, $base=62, $index=false ) {
if (! $base ) {
$base = strlen( $index );
} else if (! $index ) {
$index = substr ( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, $base );
}
$out = 0;
$len = strlen( $num ) - 1;
for ( $t = 0; $t <= $len; $t++ ) {
$out = $out + strpos( $index, substr( $num, $t, 1 ) ) * pow( $base, $len - $t );
}
return $out;
}
?>
上面只是說了下實現的原理,如果要大規模的使用,後端可以拋棄數據,用 key-value數據庫存儲,比如ttserver,將會有很高的性能提升。
如果改下ttserver的源代碼,通過ttserver的http接口直接跳轉,那麼性能 將會非常高,一台機器一天提供上10億次的中專都不是問題。用兩台機器就可以 實現高可用了,這種服務都不怎麼耗費流量的。