我試圖根據用戶ID生成一個隨機數的均勻分佈。也就是說,我希望每個用戶的隨機數在用戶請求隨機數的任何時間保持不變(但用戶不需要存儲該數字)。我現在的算法(在PHP)來算的分佈,對於給定的大陣用戶ID $arr
的是:哈希函數的隨機性,如SHA1
$range = 100;
$results = array_fill(0, $range, 0);
foreach ($arr as $userID) {
$hash = sha1($userID,TRUE);
$data = unpack('L*', $hash);
$seed = 0;
foreach ($data as $integer) {
$seed ^= $integer;
}
srand($seed);
++$results[rand(0, $range-1)];
}
人們希望這會產生一個近似均勻分佈。但它不!我已經檢查過,以確保$arr
中的每個值都是唯一的,但列表中的一個條目總是比其他條目中的條目多得多。有沒有更好的方法來生成一個字符串的散列,它會給出一個近似均勻的分佈?顯然,SHA不能勝任這項工作。我也嘗試過MD5和簡單的crc32,所有的結果都一樣!?
我瘋了嗎?事實上,我唯一的解釋是否證實$arr
中的每個條目都是唯一的?
我不確定你要求什麼。你想爲每個用戶提供一個唯一的隨機數字嗎?爲什麼不'sha1($ userId。$ salt)'? – 2012-08-01 23:09:51
有一些缺失。我無法運行此代碼,看看「一個條目獲得更多的活動」是什麼意思。你還應該注意到SHA-1並不是隨機設計的,它被設計成僞隨機的,其碰撞率低於2^160的組合。我想我在某處讀到,PHP中的隨機生成器在隨後的每次調用中都會變得更「隨機」,因此在播種之後直接調用它可能不夠。與mt_rand一起去看看是否有所作爲。 – Leigh 2012-08-01 23:15:57
我不明白爲什麼你會期望隨機任何東西均勻分佈,即使設置種子。即使使用數字1-100作爲種子的for循環也不是均勻分佈的。 http://codepad.viper-7.com/LxeHhu 3個號碼出現3次,而31/100號碼出現0次。 – 2012-08-01 23:35:20