2014-04-11 10 views
21

Czy funkcja LRAVEL str_random() jest na tyle przypadkowa, że ​​mogę jej używać do identyfikatorów?Laravel str_random() lub funkcja niestandardowa?

Na przykład

str_random(32); 

Wytwarza losowy ciąg o długości 32 składa się ze znaków alfanumerycznych, [A-A-Z 0-9] (62 znaków w sumie).

Co oznacza 2272657884496751345355241563627544170162852933518655225856 możliwości.

Jednak moje pytanie brzmi, czy to będzie wystarczająco dobre? Czy powinienem rozważyć użycie UUID lub innej niestandardowej funkcji.

+0

Można zawsze upewnij się, że nie jest to duplikat przed zapisaniem go, jak podczas generowania unikalnych ślimaki. Oczywiście jest to mało prawdopodobne. – BenjaminRH

Odpowiedz

41

str_random (Str::random()) próbuje użyć openssl_random_pseudo_bytes, który jest generatorem liczb pseudolosowych zoptymalizowanym pod kątem kryptografii, a nie unikalnością. Jeśli openssl_random_pseudo_bytes nie jest dostępny, to wraca do quickRandom():

public static function quickRandom($length = 16) 
{ 
    $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 

    return substr(str_shuffle(str_repeat($pool, 5)), 0, $length); 
} 

W moim kodu opinia quickRandom nie jest wiarygodne dla wyjątkowość ani kryptografii.

Tak, mając openssl_random_pseudo_bytes i używając 32 bajtów jest prawie niemożliwe, aby zobaczyć kolizji, ale nadal jest to możliwe. Jeśli chcesz się upewnić, że ciągi/liczby będą unikatowe (99,99%), lepiej użyj funkcji UUID. To jest to, czego normalnie używam:

/** 
* 
* Generate v4 UUID 
* 
* Version 4 UUIDs are pseudo-random. 
*/ 
public static function v4() 
{ 
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x', 

    // 32 bits for "time_low" 
    mt_rand(0, 0xffff), mt_rand(0, 0xffff), 

    // 16 bits for "time_mid" 
    mt_rand(0, 0xffff), 

    // 16 bits for "time_hi_and_version", 
    // four most significant bits holds version number 4 
    mt_rand(0, 0x0fff) | 0x4000, 

    // 16 bits, 8 bits for "clk_seq_hi_res", 
    // 8 bits for "clk_seq_low", 
    // two most significant bits holds zero and one for variant DCE1.1 
    mt_rand(0, 0x3fff) | 0x8000, 

    // 48 bits for "node" 
    mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff) 
    ); 
} 

Generuje VALENT RFC 4211 COMPLIANT wersja 4 UUID.

Sprawdź to: http://en.wikipedia.org/wiki/UUID#Random%5FUUID%5Fprobability%5Fof%5Fduplicates

+0

Gdzie podajesz "jeśli jest dostępny" w odniesieniu do openssl, dlaczego tak nie jest? Jaka jest najlepsza metoda unikalności, ponieważ będę używać łańcuchów jako identyfikatorów. – Mike

+0

W tym wierszu: https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Str.php#L190, Taylor sprawdzić, czy jest dostępny, więc muszę założyć, że nie zawsze będzie. –

+0

Twoim zdaniem, czy wystarczy quickRandom? gdybym miał sprawdzić, czy jest to oczywiście unikatowe, zanim go zapiszę. Szanse na dwie kolizje występujące kolejno są bardzo niewielkie ...? – Mike

Powiązane problemy