2010-01-20 60 views
1

客戶端和我正在集思廣益,從數字用戶標識(由數據庫生成)生成用戶名。關鍵要求是用戶名是唯一的。將整數映射到用戶名

最明顯的解決方案是設置用戶名等於用戶名。但是一個重要的要求是用戶名不是「明顯順序」的 - 所以雖然用戶ID可能會有4000,4001,4002,4003,但客戶端不希望用戶看到用戶名中的進展,即使這些數字最終將被使用。

這也將是可取的用戶名的長度爲compact--也就是長度不長,直到用戶ID已經到了有必要長度增長點。

有什麼建議嗎?

編輯: 大部分的答案都假定機制的安全性important--事實並非如此。客戶只是不希望誰是用戶名中的「高級」成員。

一個用戶名的主要目標是,他們很容易記住,只要hash並不是那麼好。

字母數字都還好,但客戶端有一個關於分配潛在的「壞」,用戶名關注。 fpq321會沒事的,ass123不會。這些將成爲用戶的公衆「處理」。

+0

他們爲什麼不能順序?爲了防止他們被猜到? – RossFabricant 2010-01-20 19:10:38

+0

我認爲這不是一個安全問題,而是一個心理問題;他們不希望用戶感覺不太重要或遲到聚會,因爲他們得到了更高(並因此更糟糕)的用戶名。 – justkevin 2010-01-20 19:35:16

回答

1

您是否考慮過使用GUID?這很長,但你不會得到重疊。或者,如何處理MD5哈希?

1

如果他們沒有對人友善閱讀,你可以使用MD5或類似的哈希值。這總是輸出相同的長度,並且「從不」有任何碰撞。當然,我會鬆散地使用「never」這個詞。

雖然應該適合您的需求。

+0

將HMAC放在MD5之上,它更加「安全」。需要注意使用簡單整數的MD5。你至少需要一個前綴或後綴。每個32位整數都有不少MD5彩虹表。即使是一些專注於「密碼恢復」的搜索引擎,也可以以毫秒爲單位反轉int的MD5。 – pestilence669 2010-01-20 19:36:02

1

一種可能的方法是對用戶標識運行散列函數。您可以使用順序探測。例如,如果一個用戶ID散列到300,但已在使用,你下次檢查301,然後302然後303

4

我傾向於選擇從單詞表+隨機數隨機單詞。如果您沒有獨特的東西,請重複沖洗&。碰撞是很少見的,特別是如果你使用兩個大小相當的單詞列表。例如:

單詞表阿名詞,例如

  • 探戈
  • 布拉沃
  • 阿爾法

單詞表乙形容詞或動詞

  • 海量
  • 光輝
  • 噁心

所以,一些示例將是 「DisgustingTango1208」, 「GloriousAlpha1912」, 「MassiveAlpha15」 等的優點該方法是,詞語是用戶更容易記住。只要你保持數字低,他們也不會造成問題,遠遠少於16 +字母數字字符。

我知道這不符合長度/增長要求,但是這樣做可以讓您深入瞭解序列的線性(範圍爲1,000)。所以,看起來,人們可以通過1000次暴力嘗試獲得ID#。

1

您可以稍微轉換整數 - 重新排列其字節 - 將字節1替換爲字節3,將字節2替換爲字節4等,並將其用作用戶名。雖然這不一定保持緊湊(因爲它確實使得數量更少的數字更大)。

比如像:

BYTE b1 = i&0xFF; 
BYTE b2 = (i>>8)&0xFF; 
BYTE b3 = (i>>16)&0xFF; 
BYTE b4 = (i>>24)&0xFF; 

int nTransformed = (b2<<24) | (b1<<16) | (b3<<8) | b4; 

這讓他們獨一無二的,但沒有明顯的順序。

1

如果您想保留用戶名儘可能短的用戶ID,你可以做這樣的事情:

<?php 
// function generates (always the same) username from an ID 
function get_username($id){ 
    $i=0; 
    $return=null; 
    // define some strings used to generate the usernames (must be 10 chars long) 
    $string1=str_split('abcdefghij'); 
    $string2=str_split('KLMNOPQRST'); 
    $string3=str_split('3274190258'); 
    $string4=str_split('ANYSTRINGY'); 
    $string5=str_split('TENCHARSLO'); 
    if($splitted=str_split($id)){ // split username 
     foreach($splitted as $i => $char){ // loop trough each number of uses_id 
      if($i==0) $return .= $string1[(intval($char))]; // 1st char is picked from $sting1 
      elseif($i==1) $return .= $string2[(intval($char))]; 
      elseif($i==2) $return .= $string3[(intval($char))]; 
      elseif($i==3) $return .= $string4[(intval($char))]; 
      else $return .= $string5[(intval($char))]; // from 5 chars, pick from sting 5 
     } 
    } 
    return (!empty($return))?$return:false; // return username or false if argument is empty 
} 
get_username(45879); 
?> 
0

(它只是由[字符] [標誌] [其它號碼]替換數)這個問題的通常解決方案是讓用戶選擇他們自己的用戶名,然後將其與用作主鍵的用戶標識相關聯。