首頁  >  文章  >  後端開發  >  PHP 的 uniqid 函數所產生的 id 真的是唯一的呢?

PHP 的 uniqid 函數所產生的 id 真的是唯一的呢?

步履不停
步履不停原創
2019-06-06 15:48:323732瀏覽

PHP 的 uniqid 函數所產生的 id 真的是唯一的呢?

最近使用到了 uniqid,就產生了疑問? uniqid 產生的 id 由什麼組成?真的是唯一的麼?什麼情況下會產生衝突?

從文件中看到uniqid 函數有兩個參數

PHP 的 uniqid 函數所產生的 id 真的是唯一的呢?

#uniqid 的結構

看原始碼:

PHP_FUNCTION(uniqid)
{
    ...
    gettimeofday((struct timeval *) &tv, (struct timezone *) NULL);
    sec = (int) tv.tv_sec;
    usec = (int) (tv.tv_usec % 0x100000);

    ...    if (more_entropy) {
        uniqid = strpprintf(0, "%s%08x%05x%.8F", prefix, sec, usec, php_combined_lcg() * 10);
    } else {
        uniqid = strpprintf(0, "%s%08x%05x", prefix, sec, usec);
    }

    RETURN_STR(uniqid);
}

基本上就了解清楚了。 uniqid 是由四個部分組成:

prefix + sec + usec + “.” + php_combined_lcg

其中 prefix 就是 uniqid 函數的第一個參數。它是一個字串,傳遞進來什麼,就直接回傳什麼。

sec 是目前時脈的秒,usec 是毫秒,這兩個值都是從 gettimeofday 取得的。換句話說,只要在一台機器上,兩個 php 程式在同一個毫秒內取得的 sec 和 usec 是一樣的。

php_combined_lcg 是由 uniqid 的第二個參數決定的,它是一個墒值,它是使用線性同餘產生一個 0 ~ 1 之間的隨機數。如果第二個參數為 true,就有這個值,如果第二個參數為 false,就沒有這個值。

例如:

➜  ~ php -r 'echo uniqid("my_", true);'my_5afe9b414c2141.76621929

結論

所以說,如果我們單純使用uniqid() 這個方法,不帶任何參數的話,這個方法只能保證單一進程,在同一個毫秒內是唯一的。如果使用uniqid("", true)。帶了一個墒值,自身已經有一個隨機的方式可以保證生成的id的隨機性了。但由於線性同餘是比較簡單的產生隨機數的演算法,隨機性有可能還不夠,所以,網路上流傳的一種更隨機數值的方式是:

uniqid(mt_rand(), true)

其中mt_rand() 產生隨機數就不是用線性同餘產生隨機數的方式了,而是使用Mersenne Twister Random Number Generator (梅森旋轉演算法)。換句話說,上面這個 id 由兩種隨機演算法 + 時間戳產生。基本上,這個演算法在很大程度上能保證唯一性了(如果要問衝突率的話,估計只有數學系學生能研究出來了...)。

上面的這個給出的id會有一個點號,而且長度並不是128bit。如果希望產生uuid,就需要一個hash,不管是md5,sha1 都是可以選擇的。所以網路上又有一種產生唯一碼的方式。 (php影片教學

md5(uniqid(mt_rand(), true))

但是,本質上,這兩種方式的隨機性是相等的。

md5(uniqid(mt_rand(), true))--------親證這個效果好,不會重,就是沒規律----我自己的話

以上是PHP 的 uniqid 函數所產生的 id 真的是唯一的呢?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn