2010-09-11 232 views
5

我需要一個大的(比如說,128位大)的隨機數生成器在PHP中。我正在考慮將此數字作爲十六進制存儲在字符串中。大隨機數生成

請注意,這是一個登錄系統,提到需要一個「隨機」數字,所以我猜我真的需要它「足夠隨機」(因爲我知道僞隨機是從未真正隨機)。

我正在考慮的算法是一次生成第一個十六進制數字,然後將它連接在一起。就像這樣:

$random = ''; 
for ($i = 0; $i < 32; ++$i) { 
    $digit = rand(0, 15); 
    $random .= ($digit < 10 ? $digit : ($digit - 10 + 'a')); 
} 
return $random; 

我能相信這個函數返回良好的僞隨機數還是我的東西我真的不應該搞亂?

回答

4

嘗試:

for ($str = '', $i = 0; $i < $len; $i++) { 
    $str .= dechex(mt_rand(0, 15)); 
} 
1

我經常看到的只是在做類似的登錄系統,此處理:

$salt = "big string of random stuff"; // you can generate this once like above 
$token = md5($salt . time()); // this will be your "unique" number 

MD5哈希值可以有衝突,但是這是非常有效和非常簡單。

+0

爲什麼不直接替換$ salt by rand()?難道它不是隨機的嗎?哎呀,可能更隨機。 – luiscubal 2010-09-11 20:53:46

+0

這是真的,但如果你想這樣做,但使用rand()會否定你對比期望散列的能力。例如。在密碼的情況下,你經常會用鹽對用戶的密碼進行散列 - 然後,因爲你大概是唯一知道鹽的人,那麼你可以比較你記錄在該用戶數據庫中的散列與「期望的散列「,你可以驗證它是正確的。 – julio 2010-09-16 16:37:12

3

幾年前我問過這個問題,從那以後,我對這個主題的認識有所提高。

首先,我提到我想要一個登錄系統的隨機數字。登錄系統是安全機制。 這意味着登錄系統依賴的任何隨機數發生器應該是加密安全

PHP的randmt_rand不是加密安全的。

在這些情況下,最好是安全而不是遺憾。有專門設計爲安全的隨機數發生器,特別是openssl_random_pseudo_bytes(不幸的是,這種隨機數發生器並不總是可用的 - 您必須啓用OpenSSL擴展才能使其工作)。在* NIX系統(如Linux)上,字節也從/dev/urandomcan be used中讀取。

不幸的是(對於這個問題),這兩種方法都返回二進制數據而不是十六進制數據。幸運的是,PHP已經有一個函數來解決這個問題,bin2hex,它適用於任何長度的字符串。

因此,這裏的代碼會是什麼樣子:

function generate_secure_random_hex_string($length) { 
    // $length should be an even, non-negative number. 

    // Because each byte is represented as two hex digits, we'll need the binary 
    // string to be half as long as the hex string. 
    $binary_length = $length/2; 

    // First, we'll generate the random binary string. 
    $random_result = openssl_random_pseudo_bytes($binary_length, $cstrong); 

    if (!$cstrong) { 
     // The result is not cryptographically secure. Abort. 
     // die() is just a placeholder. 
     // There might be better ways to handle this error. 
     die(); 
    } 

    //Convert the result to hexadecimal 
    return bin2hex($random_result); 
} 

// Example: 
echo generate_secure_random_hex_string(32); 
0

由於PHP 5.3:

function getRandomHex($num_bytes=4) { 
    return bin2hex(openssl_random_pseudo_bytes($num_bytes)); 
} 

爲了您的128位例如:

$rand128 = getRandomHex(16);