網上搜尋,發現大體都類似如下:
$chars = md5(uniqid(mt_rand(), true)); $uuid = substr($chars,0,8) . '-'; $uuid .= substr($chars,8,4) . '-'; $uuid .= substr($chars,12,4) . '-'; $uuid .= substr($chars,16,4) . '-'; $uuid .= substr($chars,20,12); return $prefix . $uuid;
mt_srand ( ( double ) microtime () * 10000 ); //optional for php 4.2.0 and up.隨便數播種,4.2.0以後不需要了。 $charid = strtoupper ( md5 ( uniqid ( rand (), true ) ) ); //根據目前時間(微秒計)產生唯一id. $hyphen = chr ( 45 ); $uuid = '' . substr ( $charid, 0, 8 ) . $hyphen . substr ( $charid, 8, 4 ) . $hyphen . substr ( $charid, 12, 4 ) . $hyphen . substr ( $charid, 16, 4 ) . $hyphen . substr ( $charid, 20, 12 ); return $uuid;
看了UUID的說明,怎麼感覺這些產生方法 撞擊率 達不到標準啊?
回複內容:
網上搜尋,發現大體都類似如下:
$chars = md5(uniqid(mt_rand(), true)); $uuid = substr($chars,0,8) . '-'; $uuid .= substr($chars,8,4) . '-'; $uuid .= substr($chars,12,4) . '-'; $uuid .= substr($chars,16,4) . '-'; $uuid .= substr($chars,20,12); return $prefix . $uuid;
mt_srand ( ( double ) microtime () * 10000 ); //optional for php 4.2.0 and up.隨便數播種,4.2.0以後不需要了。 $charid = strtoupper ( md5 ( uniqid ( rand (), true ) ) ); //根據目前時間(微秒計)產生唯一id. $hyphen = chr ( 45 ); $uuid = '' . substr ( $charid, 0, 8 ) . $hyphen . substr ( $charid, 8, 4 ) . $hyphen . substr ( $charid, 12, 4 ) . $hyphen . substr ( $charid, 16, 4 ) . $hyphen . substr ( $charid, 20, 12 ); return $uuid;
看了UUID的說明,怎麼感覺這些產生方法 撞擊率 達不到標準啊?
目前很多所謂PHP產生UUID的方法都以隨機數最為其演算法的基礎,這雖然在實踐中很難出現重複的幾率,但在理論上顯然是行不通的。
這裡用MongoDb的ObjectId作為例子,個人覺得這種產生方法是可以引入到PHP中的。
ObjectId主要分為四塊:時間戳記、毫秒數、機器碼、自增計數。
前兩者就不用細說了,PHP都可以取到,重點在後兩者上。
機器碼主要用於避免在不同主機間產生相同的UUID。
機器碼目前主要的產生方法是根據硬體資訊進行散列計算出,而這個方法並不適用於PHP。
主要因為兩點,一是PHP不能直接獲得硬體資訊(需要通過擴充或者執行本地命令等方法),二是PHP請求與請求之間無法共用資料,所以每次請求都得拉取機器碼,對效能影響很大。
解決這一問題有個很簡單的辦法,就是在不同機器先計算出機器碼,之後直接寫入設定檔,PHP處理時直接讀取即可。
自增計數主要用於避免在並發處理中產生相同的UUID。
對於自增來說,PHP由於不能在請求間共用資料,所以不能直接實現自增計數。
解決這一問題我們可以引入PHP的兩個擴充,分別是Semaphore和Shared Memory,這兩者都在PHP源碼中整合,通過--enable-sysvsem和--enable-sysvshm就能開啟。我們只需要把自增數放置在共用記憶體中,再通過訊號量限制訪問,即可達到並發請求共用自增技術的目的了。當然,自增也能通過其他工具來實現。
Linux核心提供有UUID產生介面:
cat /proc/sys/kernel/random/uuid
Linux上一切皆檔案,不管什麼程式,讀取檔案就能擷取一個UUID.
自行產生一個唯一值:
php best.php
另外貌似用openssl_random_pseudo_bytes也能產生不錯的隨機串:
echo base64_encode(openssl_random_pseudo_bytes(32));