簡體   English   中英

生成500萬個唯一代碼

[英]Generate 5 million unique codes

我正在尋找一種有效的方法來生成7個字符(字母,數字,特殊字符)的500萬個唯一代碼。

基本上,我的想法是生成具有唯一約束的表。 然后生成一個代碼,將其插入數據庫,看看它是否被“接受”(表示新代碼),直到我們擁有500萬個唯一代碼為止。

或者,他們的想法是生成一個包含500萬個唯一代碼的數組,然后將它們立即一次插入數據庫中,以查看有多少代碼使其成為數據庫(唯一)。

第三種選擇是創建一個代碼,檢查它是否已經存在,如果沒有將其插入數據庫中。

現在我的問題是我應該使用哪種方法-可能會遇到一個問題。 或者,還有更好的方法?

非常感謝!

選擇一個適當的函數來生成一個隨機代碼; 出於說明目的,我將使用以下代碼:

function generateCode() {
    return substr(bin2hex(random_bytes(4)), 0, 7);
}

請參閱https://stackoverflow.com/a/22829048/476和其他答案,以選擇適合您的東西。 重要的一點是它使用了很好的隨機性來源 ,可以是random_bytesrandom_intopenssl_random_pseudo_bytes/dev/urandom 這樣可以最大程度地減少兩次調用此函數產生相同輸出的機會。

從那里開始,只需使用數組鍵對值進行重復數據刪除即可:

$codes = [];

while (count($codes) < 5000000) {
    $codes[generateCode()] = null;
}

$codes = array_keys($codes);

如果 generateCode是足夠隨機的,則以這種方式生成代碼的沖突應該很少,並且不應有太多開銷。 即使這只是一次操作,效率也不是最重要的。 500萬個短字符串當然應該可以毫無問題地裝入內存。 然后,您可以將它們全部批量插入數據庫中。

鑒於您要生成唯一標識(如難以猜測的優惠券代碼)的目的,我想說的是,您應該生成一個將“唯一”部分和“隨機”部分組合在一起的唯一標識符

  • “唯一”部分可以是單調遞增的計數器(例如,支持數據庫中的自動遞增的行號),可以選擇用作全周期線性同余生成器的種子(該生成器會偽隨機地遍歷其所有可能值重復之前的期限)。
  • “隨機”部分只是一個由密碼隨機數生成器生成的隨機數(對於PHP來說是random_int )。 通常,隨機部分越長,可預測性就越差。

此外,出於生成唯一優惠券代碼的目的,沒有什么理由將自己限制為7個字符的代碼,尤其是在不需要最終用戶直接輸入這些代碼的情況下。 另請參閱此問題

function generateRandomString($length = 7) {

    // you can update these with new chars
    $characters = '!@#$%^&*()_+0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $charactersLength = strlen($characters);
    $randomString = '';
    for ($i = 0; $i < $charactersLength; $i++) {
        $randomString .= $characters[rand(0, $charactersLength - 1)];
    }
    return $randomString;
}

現在使用數組存儲代碼:

$codes = array();
while(count($codes)!=5000000){
   $code =  generateRandomString();
   $codes[$code] =  $code;
}

$codes鍵和值都具有相同的代碼。

是否需要將您想要的代碼插入數據庫?

最好不要不斷地向數據庫請求並嘗試它是否唯一。

您可以先將代碼存儲到數組,然后再將其放入數據庫。

偽代碼:

  1. 生成唯一的500萬個代碼,插入哈希表或數組中。 //當您插入新哈希表時,請檢查哈希表是否存在。

  2. 然后,您現在將此哈希表或數組插入數據庫中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM