Używając Random::alphanumericString($length)możesz uzyskać ciągi z 0-9a-zA-Z, które pochodzą z kryptograficznie zabezpieczonych losowych danych.
krakaj
Odpowiedzi:
162
$rand = substr(md5(microtime()),rand(0,26),5);
Byłoby moim najlepszym przypuszczeniem - chyba że szukasz też znaków specjalnych:
$seed = str_split('abcdefghijklmnopqrstuvwxyz'.'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.'0123456789!@#$%^&*()');// and any other characters
shuffle($seed);// probably optional since array_is randomized; this may be redundant
$rand ='';foreach(array_rand($seed,5)as $k) $rand .= $seed[$k];
Uwaga: przyrostowe oznacza łatwiejsze do odgadnięcia; Jeśli używasz tego jako soli lub tokena weryfikacyjnego, nie rób tego. Sól (teraz) „WCWyb” oznacza za 5 sekund „WCWyg”)
Problem z używaniem md5()polega jednak na tym, że otrzymujesz ciąg złożony z 16-znakowego zestawu (10 cyfr i ado f, czyli 4 bity na znak łańcucha). To może być wystarczające do niektórych celów, ale może być zbyt małe do celów kryptograficznych (pięć znaków z 16 symboli = 16 ^ 5 = 20 bitów = 1048576 możliwości).
Łuk
3
array_rand($seed, 5)zwróci klucz tablicy, a nie wartość, więc twój kod nie zadziała
alumi
1
Myślę, że używanie kryptograficznej funkcji skrótu do generowania losowych znaków jest co najmniej niewłaściwe.
gronostaj
Jest to możliwe także zawierać ", 'i ukośnik w $charset? Czy muszę używać sekwencji ucieczki, aby uwzględnić te znaki?
maja
1
Drugi fragment nawet nie używa $lenparametru wejściowego ... zapomniałeś o tym?
Ciekawe rozwiązanie ... bardzo zwięzłe, choć zastanawiam się, czy jest to szybsze czy wolniejsze niż używanie for. Jednak nie zawracam sobie głowy testem porównawczym :-)
Arc
@matthew str_shuffle będzie produkować duplikaty w sposób ciągły
SCC
@ user2826057: str_shuffle('ab')dałby abalbo baale nigdy aa. Dodanie str_repeatpozwala na to. Ale to powiedziawszy, rozwiązanie, które podałem, nie jest tak naprawdę poważne ... chociaż działa.
Matthew,
2
Istnieje prawdopodobieństwo 1/60466176, że tak się stanie, zakładając, że RNG jest równomiernie rozłożone.
Matthew,
1
Jest to idealne rozwiązanie w naszym przypadku generowania kodów kuponów. Usunęliśmy mylące znaki, jak l, i, 1, 0, O, etc i z 500 kuponów dostał żadnych duplikatów.
Luke Cousins
25
Szybkim sposobem jest użycie najbardziej niestabilnych znaków funkcji uniqid .
Poniższe powinny zapewnić najmniejszą szansę na powielenie (możesz chcieć zastąpić mt_rand()lepszym źródłem liczb losowych, np. Z /dev/*randomlub z identyfikatorów GUID):
Pierwszy przykład, bardziej sprytny z wynikiem $. = $ Znaków [mt_rand (0, strlen ($ znaków) -1)]
hamboy75
W takim przypadku należy wcześniej określić długość i zapisać ją przynajmniej w zmiennej. Używanie strlen()w pętli jest niepotrzebnym narzutem, zwłaszcza jeśli już wiesz, że zestaw znaków nie zmieni się w międzyczasie.
Łuk
Wątpię, php jest zoptymalizowany, w każdym razie jest to opcja :)
hamboy75
7
Zawsze używam do tego tej samej funkcji, zwykle do generowania haseł. Jest łatwy w użyciu i przydatny.
Uważam, że używanie funkcji skrótu jest przesadą w przypadku tak prostego zadania, jak generowanie sekwencji losowych cyfr szesnastkowych. dechex+ mt_randwykona tę samą pracę, ale bez zbędnej pracy kryptograficznej. str_padgwarantuje 5-znakową długość ciągu wyjściowego (jeśli liczba losowa jest mniejsza niż 0x10000).
Podwójne prawdopodobieństwo zależy od mt_randwiarygodności. Mersenne Twister jest znany z wysokiej jakości losowości, więc powinien dobrze pasować do zadania.
Nie wiedziałem też, jak to zrobić, dopóki nie pomyślałem o użyciu PHP array. I jestem prawie pewien, że jest to najprostszy sposób generowania losowego ciągu lub liczby z tablicami. Kod:
Jak zauważył Archimedix , nie gwarantuje to zwrócenia „najmniejszej możliwości powielenia”, ponieważ liczba kombinacji jest niska dla podanego zakresu znaków. Będziesz musiał albo zwiększyć liczbę znaków, albo pozwolić na dodatkowe (specjalne) znaki w ciągu. Myślę, że w twoim przypadku lepsze byłoby pierwsze rozwiązanie.
Używanie time()jest do 1 miliona razy bardziej przewidywalne niż microtime().
Łuk
Zwróć także uwagę na moje komentarze do odpowiedzi Brada, większym problemem jest to, że wygenerowany hash jest reprezentacją szesnastkową składającą się z 16 prawidłowych znaków, dlatego pozostawia tylko 1024 warianty dla $str.
Łuk
Być może @Archimedix, ale OP nie pytał o bezpieczeństwo, pytanie zostało zdefiniowane tak, aby mieć algorytm generowania ciągów składający się z kombinacji 5x26 różnych znaków i unikający duplikatów. To prawdopodobnie dla numeru referencyjnego potwierdzenia w procesie rejestracji (lub procesu rozliczeniowego), lub coś w tym stylu
Yanick Rochon
To było moje zrozumienie, że nie poprosić o najmniejszej możliwości uzyskania powielane , a ten ma 0,1% prawdopodobieństwo (1 w 1024), co mogło być prawie 1 do 1 miliarda.
Łuk
jeśli jednak potrzebujesz wygenerować klucz referencyjny składający się z 5 znaków i dać temu klientowi / klientowi, nie chcesz ich dawać " ˫§»⁋⅓" tylko dlatego, że jest bezpieczniejszy ... zwiększ swój klucz referencyjny do 7 lub więcej znaków . (BTW: poprawka w moim poprzednim komentarzu, to 5x36 znaków)
function cvf_ps_generate_random_code($length=10){
$string ='';// You can define your own characters here.
$characters ="23456789ABCDEFHJKLMNPRTVWXYZabcdefghijklmnopqrstuvwxyz";for($p =0; $p < $length; $p++){
$string .= $characters[mt_rand(0, strlen($characters)-1)];}return $string;}
Porada dla profesjonalistów - Dołącz wyjaśnienie, w jaki sposób Twoja odpowiedź rozwiązuje problem PO i dlaczego może się różnić od innych już udzielonych odpowiedzi.
0-9a-zA-Z
?Random::alphanumericString($length)
możesz uzyskać ciągi z 0-9a-zA-Z, które pochodzą z kryptograficznie zabezpieczonych losowych danych.Odpowiedzi:
Byłoby moim najlepszym przypuszczeniem - chyba że szukasz też znaków specjalnych:
Przykład
I dla jednego opartego na zegarze (mniej kolizji, ponieważ jest przyrostowy):
Uwaga: przyrostowe oznacza łatwiejsze do odgadnięcia; Jeśli używasz tego jako soli lub tokena weryfikacyjnego, nie rób tego. Sól (teraz) „WCWyb” oznacza za 5 sekund „WCWyg”)
źródło
md5()
polega jednak na tym, że otrzymujesz ciąg złożony z 16-znakowego zestawu (10 cyfr ia
dof
, czyli 4 bity na znak łańcucha). To może być wystarczające do niektórych celów, ale może być zbyt małe do celów kryptograficznych (pięć znaków z 16 symboli = 16 ^ 5 = 20 bitów = 1048576 możliwości).array_rand($seed, 5)
zwróci klucz tablicy, a nie wartość, więc twój kod nie zadziała"
,'
i ukośnik w$charset
? Czy muszę używać sekwencji ucieczki, aby uwzględnić te znaki?$len
parametru wejściowego ... zapomniałeś o tym?Jeśli
for
brakuje pętli, oto, czego lubię używać:źródło
str_shuffle('ab')
dałbyab
alboba
ale nigdyaa
. Dodaniestr_repeat
pozwala na to. Ale to powiedziawszy, rozwiązanie, które podałem, nie jest tak naprawdę poważne ... chociaż działa.l
,i
,1
,0
,O
, etc i z 500 kuponów dostał żadnych duplikatów.Szybkim sposobem jest użycie najbardziej niestabilnych znaków funkcji uniqid .
Na przykład:
źródło
Możesz spróbować po prostu w ten sposób:
więcej szczegółów: http://forum.arnlweb.com/viewtopic.php?f=7&t=25
źródło
Poniższe powinny zapewnić najmniejszą szansę na powielenie (możesz chcieć zastąpić
mt_rand()
lepszym źródłem liczb losowych, np. Z/dev/*random
lub z identyfikatorów GUID):EDYCJA:
Jeśli obawiasz się o bezpieczeństwo, naprawdę nie używaj
rand()
lubmt_rand()
i sprawdź, czy Twoje urządzenie do losowych danych jest w rzeczywistości urządzeniem generującym losowe dane, a nie zwykłym plikiem lub czymś przewidywalnym/dev/zero
.mt_rand()
uważane za szkodliwe:https://spideroak.com/blog/20121205114003-exploit-information-leaks-in-random-numbers-from-python-ruby-and-php
EDYCJA: Jeśli masz obsługę OpenSSL w PHP, możesz użyć
openssl_random_pseudo_bytes()
:źródło
strlen()
w pętli jest niepotrzebnym narzutem, zwłaszcza jeśli już wiesz, że zestaw znaków nie zmieni się w międzyczasie.Zawsze używam do tego tej samej funkcji, zwykle do generowania haseł. Jest łatwy w użyciu i przydatny.
źródło
Wygląda na to, że str_shuffle będzie do tego dobrym zastosowaniem. Rozdaj shuffle dowolnymi postaciami, które chcesz.
źródło
źródło
Jeśli jest w porządku, że otrzymasz tylko litery AF, oto moje rozwiązanie:
Uważam, że używanie funkcji skrótu jest przesadą w przypadku tak prostego zadania, jak generowanie sekwencji losowych cyfr szesnastkowych.
dechex
+mt_rand
wykona tę samą pracę, ale bez zbędnej pracy kryptograficznej.str_pad
gwarantuje 5-znakową długość ciągu wyjściowego (jeśli liczba losowa jest mniejsza niż 0x10000).Podwójne prawdopodobieństwo zależy od
mt_rand
wiarygodności. Mersenne Twister jest znany z wysokiej jakości losowości, więc powinien dobrze pasować do zadania.źródło
Nie wiedziałem też, jak to zrobić, dopóki nie pomyślałem o użyciu PHP
array
. I jestem prawie pewien, że jest to najprostszy sposób generowania losowego ciągu lub liczby z tablicami. Kod:Możesz użyć tej funkcji w ten sposób
źródło
Podobna do odpowiedzi Brada Christiego , ale używająca
sha1
algorytmu dla znaków0-9a-zA-Z
i poprzedzona losową wartością:Ale jeśli ustawiłeś zdefiniowane (dozwolone) znaki:
** AKTUALIZACJA **
Jak zauważył Archimedix , nie gwarantuje to zwrócenia „najmniejszej możliwości powielenia”, ponieważ liczba kombinacji jest niska dla podanego zakresu znaków. Będziesz musiał albo zwiększyć liczbę znaków, albo pozwolić na dodatkowe (specjalne) znaki w ciągu. Myślę, że w twoim przypadku lepsze byłoby pierwsze rozwiązanie.
źródło
time()
jest do 1 miliona razy bardziej przewidywalne niżmicrotime()
.$str
.˫§»⁋⅓
" tylko dlatego, że jest bezpieczniejszy ... zwiększ swój klucz referencyjny do 7 lub więcej znaków . (BTW: poprawka w moim poprzednim komentarzu, to 5x36 znaków)działa dobrze w PHP (php 5.4.4)
Live Demo
źródło
Źródło: funkcja PHP generująca losowe znaki
Ta prosta funkcja PHP zadziałała dla mnie:
Stosowanie:
źródło
Oto moje
random 5 cents
...Nowa
password_hash()
funkcja PHP (*> = PHP 5.5) wykonuje zadanie generowania przyzwoicie długiego zestawu wielkich i małych liter oraz cyfr.Dwa konkat. łańcuchy przed i po
password_hash
funkcji $ random nadają się do zmiany.Parametry dla
$random()
* ($ a, $ b) są w rzeczywistościsubstr()
parametrami. :)UWAGA: to nie musi być funkcją, może to być również normalna zmienna .. jak jeden paskudny singliner, na przykład:
źródło
źródło
Używam tego:
Kiedy to wywołasz, ustawia długość sznurka.
Możesz także zmienić możliwe znaki w ciągu
$a
.źródło