2012-08-15 84 views
1

生成一個唯一的ID我想要實現類似Imgur一個節能系統,其中,如果用戶按下一個按鈕返回了獨特的5字符值。以下是我迄今爲止:在Javascript

數據庫後端使用自動遞增的ID開始在5308416。我使用修改後的基數函數(見下文)將這些數字ID轉換爲字符。我使用反向函數來查找字符ID的數字數據庫ID。

function genID (value) 
{ 
    var alphabet = "23456789BCDFGHJKLMNPRSTVWXYZbcdfghjkmnpqrstvwxyz"; 

    var result = ""; 
    var length = alphabet.length; 

    while (value > 0) 
    { 
     result = alphabet[value % length] + result; 
     value = Math.floor (value/length); 
    } 

    return result; 
} 

問題是這些生成的ID是非常可預測的。我的問題是,如何讓生成的ID看起來像隨機但仍然是唯一的(所以我可以將它們作爲數字在數據庫中查找)。我正在考慮使用一些加密算法,但不知道從哪裏開始。任何幫助或建議,將不勝感激(也許有更好的方式做這也是)。

+2

使用時間,它是獨一無二的,永遠不會重複! – zizoujab 2012-08-15 01:56:33

+0

除了當時鍾手動更改,或DST和其他一秒的飛躍...... – 2012-08-15 01:58:14

+0

會自動調整** Zied Jaballah **說,我想時間應該這樣做'變種的uniq =(新日期).getTime( );' – elclanrs 2012-08-15 02:01:25

回答

1

你必須要能夠去兩種方式(即轉換爲整數,以它的哈希值,然後再返回)?如果您可以存儲散列並以這種方式查找內容,那麼創建一個產生難以猜測但完整散列空間的函數相對容易。您使用素數生成一個序列,只有在所有可能的排列用盡後纔會重複。

以下PHP例子from my own code,改編自this site

function hash($len = 6) { 
    $base = 36; 
    $gp = array(1,23,809,28837,1038073,37370257 /*,1345328833*/); 
    $maxlen = count($gp); 
    $len = $len > ($maxlen-1) ? ($maxlen-1) : $len; 
    while($len < $maxlen && pow($base,$len) < $this->ID) $len++; 
    if($len >= $maxlen) throw new Exception($this->ID." out of range (max ".pow($base,$maxlen-1).")"); 
    $ceil = pow($base,$len); 
    $prime = $gp[$len]; 
    $dechash = ($this->ID * $prime) % $ceil; 
    $hash = base_convert($dechash, 10, $base); 
    return str_pad($hash, $len, "0", STR_PAD_LEFT); 
} 

這將是很容易實現,在JavaScript中,但最好你就不需要太 - 你有一個INSERT觸發器上您的表中填充了該算法的結果(當然適用於SQL)的散列字段。

+0

這是一個非常好的解決方案。下面是一個node.js實現:https://github.com/alecgorge/node-psuedohash – Dave 2012-08-15 10:06:00

0

一個不可預測的,但唯一的ID可以通過服務器端自動遞增的數字與無論是當前的日期/時間金塊或隨機數相結合進行。服務器端自動遞增數字保證唯一性,日期/時間塊或隨機數刪除可預測性。

對於字符串形式的唯一的ID都在服務器端的唯一編號作爲輸入,並在其中添加客戶端上的日期/時間金塊,你可以這樣做:

function genID(serverNum) { 
    return(serverNum + "" + (new Date).getTime()); 
} 

或使用隨機數:

function genID(serverNum) { 
    return(serverNum + "" + Math.floor(Math.random() * 100000)); 
} 

但是,這可能是最好的添加服務器上的日期/時間元素,只是存儲整個唯一ID在數據庫中存在。

+0

Javascript中的隨機數生成器非常糟糕。碰撞的數量非常大。 – Dave 2012-08-15 11:53:53

+0

@Dave - 該算法不關心隨機數發生器中是否存在碰撞(隨機數發生器會有)。如果您閱讀帖子,唯一性來自服務器生成的號碼。隨機數的加法只是使整體數字不可預測。 – jfriend00 2012-08-15 15:21:54