2010-08-18 83 views
9

任何人都可以推薦一個首選算法來使用URL縮短嗎?我使用PHP編碼。起初,我想寫一些以「a」這樣的字符開始的東西,並迭代請求,在數據庫中創建記錄,因此必須將字符遞增爲b,c,d ... A,B等等適當。PHP URL縮短算法

但是,我覺得這個算法可能非常笨重/笨拙,並且可能有更好的方法來做到這一點。

我在Google上閱讀了一下,有些人似乎正在使用數據庫ID列進行基本轉換。這不是我所熟悉的。

有人能詳細說明並向我解釋這將如何工作?一些代碼示例也會很好。

我明顯不想要一個完整的解決方案,因爲我想通過自己來學習,但只是解釋/僞代碼如何工作將是非常好的。

回答

12

大多數縮短服務僅僅是使用遞增每進入一個計數器,並從10基轉換爲64

PHP中的實現看起來是這樣的:

function encode($number) { 
    return strtr(rtrim(base64_encode(pack('i', $number)), '='), '+/', '-_'); 
} 
function decode($base64) { 
    $number = unpack('i', base64_decode(str_pad(strtr($base64, '-_', '+/'), strlen($base64) % 4, '='))); 
    return $number[1]; 
} 

$number = mt_rand(0, PHP_INT_MAX); 
var_dump(decode(encode($number)) === $number); 

encode函數接受整數,將其轉換爲字節(pack),使用Base-64編碼(base64_encode)對其進行編碼,修剪尾部填充=rtrim),並替換字符+/分別由-_strtr)。decode函數是與encode相反的函數,並且完全相反(除了添加尾部填充)。

額外使用的strtr是將original Base-64 alphabet轉換爲URL and filename safe alphabet作爲+/需要與百分比-編碼進行編碼。

+0

感謝您的建議!很多現在就讓我的牙齒進入。我將與Base64玩一玩。謝謝。 – George 2010-08-19 00:18:43

1

假設你的PRIMARY KEY是一個INT並且它是auto_increments,下面的代碼會讓你去=)。

<?php 

    $inSQL = "INSERT INTO short_urls() VALUES();"; 
    $inResult = mysql_query($inSQL); 
    $databaseID = base_convert(mysql_insert_id(), 10, 36); 

    // $databaseID is now your short URL 

?> 

編輯:包括從HGF的答案base_convert。我在原帖中忘記了base_convert。

+0

非常感謝。我可以理解,但肯定如果你只是使用數據庫ID,你被限制爲0-9的數字,所以只有Base10?以某種方式利用a-zA-Z0-9不是更好嗎?或者我有一個非常金髮的時刻... – George 2010-08-18 16:12:18

2

可以使用base_convert函數將數據庫ID從10到36進行基數轉換。

<?php 
    $id = 315; 
    echo base_convert($id, 10, 36), "\n"; 
?> 

或者你可以重用一些在頁面上的波紋管的意見提出的觀點:

http://php.net/manual/en/function.base-convert.php

1

我使用着如何從十進制轉換爲十六進制類似的算法,打破ID,但它將使用62個字符,而不是十六進制將使用的16個字符。

'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' 

例如:如果你將改變ID = 1234567890你會得到kv7yl1您的一個關鍵。

1

我採用了「輕」解決方案。在用戶請求時我產生唯一的標識符(檢查以db衝突)這蟒snipplet:

url_hash = base64.b64encode(os.urandom(int(math.ceil(0.75*7))))[:6] 

並將其存儲在DB中。

1

這裏試試這個方法:

hash_hmac('joaat', "http://www.example.com/long/url/", "secretkey"); 

它會爲你提供的散列值適合專業的縮短網址,e.g: '142ecd53'