2016-09-20 42 views
2

背景:如何使用PHP生成正確的訂單號?

我正在創建服務預訂網站。每個訂單都需要有一個唯一的訂單號。我選擇了16位數字,因爲這是以前使用的軟件。

問題

我不知道如果有將數據輸入訂單號碼,或者如果它應該只是一個純粹的隨機字符串任何好處。

如果它只是一個隨機字符串,那麼它的唯一目的就是充當一個ID。如果是這種情況,那麼爲什麼不使用增量ID呢?除此之外,爲了模糊我們爲最終用戶生成的訂單數量,我想不出有什麼好的理由。

如果將數據放入字符串是一個好主意,我應該包含哪種數據?可能是訂單的日期,但其他的我不知道。

我目前正在生成一個這樣的純粹隨機的16位字符串。

public function generateOrderNumber() 
{ 
    $time = time(); // Time (CET) to hash 
    $token = md5($time); // Hash stored in variable 
    return str_shuffle(substr($token, 0, 16)); // Hash shortened to 5 chars and randomised 
} 

但是我不確定這是否足夠生產。

+3

爲什麼不只是使用自動增量?如果你想混淆你讓它開始在一個隨機數 – NDM

+4

我們也不知道。我們完全不知道您的生產需求/需求。加上,爲什麼str_shuffle? md5哈希值總是基本上是「隨機的」。縮短它會減少密鑰空間並增加碰撞的可能性,並且洗牌並不能幫助避免碰撞。 –

+0

有道理@Marc B,謝謝澄清。我假設如果我們生成了足夠的訂單,那麼在使用MD5時有一個主鍵匹配的機會,儘管機會很小。 –

回答

3

如果您需要全局唯一性,比如跨多個數據庫間隔同步,那麼我會使用標準的128位GUID,它可以被壓縮爲16個8位字節以保持向後兼容性。 PHP有com_create_guid來生成GUID。

+0

字節可以不是8位嗎? *(我認爲4位是半字節的,16位是一個字,因此8位總是一個字節,所以你可以說'16字節'?)* – MatBailie

+0

這些天是的,但歷史上並不總是如此。我是一個C老計時器,如打卡和分時。 –

0

MD5只產生a-f0-9範圍內的值,這裏嚴格限制。你真的需要擴展這個並使用整個字母表,甚至Base62,Base64的變體減去兩個「煩人的」字符。

一個密碼隨機數字,而不是垃圾rand()產生,編碼爲5個字符的Base62值可以工作。

如果你需要的人能夠讀取和寫入這些值手工你要忽略0,爲了清楚O1lI

請記住,對於真正的短值,您可能會碰到衝突,因此您需要測試您針對UNIQUE約束所做的任何INSERT並在其失敗時重試。

+0

這些「煩人的」字符在base64中,有時是填充字符('=')http://stackoverflow.com/a/4492448/3000179? –

+0

是的,那些惱人的是'='填充字符,而且還有'+'和'/',它們混淆了URL中的值。這就是爲什麼Base62是一個受歡迎的選擇。 – tadman

+0

很好,謝謝':)' –