Jak byłoby możliwe wygenerowanie losowego, unikalnego ciągu przy użyciu cyfr i liter do użycia w łączu weryfikacyjnym? Podobnie jak w przypadku tworzenia konta w witrynie internetowej, która wysyła wiadomość e-mail z linkiem, a użytkownik musi kliknąć ten link, aby zweryfikować swoje konto ... tak ... jeden z nich.
Jak mogę wygenerować jedną z tych przy użyciu PHP?
Aktualizacja: Właśnie zapamiętałem uniqid()
. Jest to funkcja PHP, która generuje unikalny identyfikator na podstawie bieżącego czasu w mikrosekundach. Myślę, że użyję tego.
php
string
random
uniqueidentifier
Andrzej
źródło
źródło
Scott
właściwą odpowiedź. Scott używa kryptograficznie bezpiecznego generatora liczb psudo-losowych OpenSSL (CSPRNG), który wybierze najbezpieczniejsze źródło entropii w oparciu o twoją platformę.uniqid
są niepewne. Użyj czegoś takiego jakRandom::alphanumericString($length)
lubRandom::alphanumericHumanString($length)
.Odpowiedzi:
Jeśli nie musisz być absolutnie wyjątkowy w czasie:
md5(uniqid(rand(), true))
W przeciwnym razie (pod warunkiem, że określiłeś już unikalny login dla swojego użytkownika):
źródło
Właśnie zastanawiałem się, jak rozwiązać ten sam problem, ale chcę również, aby moja funkcja utworzyła token, którego można również użyć do odzyskiwania hasła. Oznacza to, że muszę ograniczyć możliwość odgadnięcia tokena. Ponieważ
uniqid
jest oparty na czasie i według php.net „zwracana wartość niewiele różni się od microtime ()”,uniqid
nie spełnia kryteriów. PHP zaleca używanieopenssl_random_pseudo_bytes()
zamiast tego do generowania bezpiecznych kryptograficznie tokenów.Szybka, krótka i konkretna odpowiedź brzmi:
który wygeneruje losowy ciąg znaków alfanumerycznych o długości = $ bajtów * 2. Niestety ma to tylko alfabet
[a-f][0-9]
, ale działa.Poniżej znajduje się najsilniejsza funkcja, jaką mogę wykonać, która spełnia kryteria (Jest to zaimplementowana wersja odpowiedzi Erika).
crypto_rand_secure($min, $max)
działa jako kropla zastępująca dlarand()
lubmt_rand
. Używa openssl_random_pseudo_bytes, aby pomóc utworzyć losową liczbę między $ min a $ max.getToken($length)
tworzy alfabet do użycia w tokenie, a następnie tworzy ciąg długości$length
.EDYCJA: Zaniedbałem cytować źródło - http://us1.php.net/manual/en/function.openssl-random-pseudo-bytes.php#104322
EDYCJA (PHP7): Wraz z wydaniem PHP7 biblioteka standardowa ma teraz dwie nowe funkcje, które mogą zastąpić / ulepszyć / uprościć powyższą funkcję crypto_rand_secure.
random_bytes($length)
irandom_int($min, $max)
http://php.net/manual/en/function.random-bytes.php
http://php.net/manual/en/function.random-int.php
Przykład:
źródło
base64_encode
zamiast,bin2hex
aby uzyskać krótszy ciąg z większym alfabetem.Zorientowana obiektowo wersja najlepiej ocenianego rozwiązania
Stworzyłem rozwiązanie obiektowe oparte na odpowiedzi Scotta :
Stosowanie
Niestandardowy alfabet
W razie potrzeby możesz użyć niestandardowego alfabetu. Po prostu przekaż ciąg znaków z obsługiwanymi znakami do konstruktora lub setera:
Oto próbki wyjściowe
Mam nadzieję, że to komuś pomoże. Twoje zdrowie!
źródło
$obj = new RandomStringGenerator;
ale którą metodę powinienem wywołać? Dziękuję Ci.generate
metodę jak w powyższym przykładzie. Wystarczy podać liczbę całkowitą, aby określić długość wynikowego ciągu.Custom Alphabet
nie zadziałało. Otrzymałem pusty sygnał wyjściowy, gdy echo. W każdym razie nie jestem nawet pewien, jaki jest pożytek z drugiego przykładu,Custom Alphabet
więc myślę, że pozostanę przy pierwszym przykładzie. Dzięki.Jestem spóźniony, ale jestem tutaj z kilkoma dobrymi danymi badawczymi opartymi na funkcjach dostarczonych przez odpowiedź Scotta . Tak więc skonfigurowałem kroplę Digital Ocean tylko na ten 5-dniowy automatyczny test i zapisałem wygenerowane unikalne ciągi w bazie danych MySQL.
Podczas tego okresu testowego użyłem 5 różnych długości (5, 10, 15, 20, 50) i dla każdej długości wstawiono +/- 0,5 miliona rekordów. Podczas mojego testu tylko 5 wygenerowało +/- 3K duplikatów z 0,5 miliona, a pozostałe długości nie wygenerowały żadnych duplikatów. Możemy więc powiedzieć, że jeśli użyjemy długości 15 lub więcej z funkcjami Scotta, możemy wygenerować wysoce niezawodne unikalne ciągi. Oto tabela z moimi danymi badawczymi:
Aktualizacja: Utworzyłem prostą aplikację Heroku przy użyciu tych funkcji, która zwraca token jako odpowiedź JSON. Dostęp do aplikacji można uzyskać na stronie https://uniquestrings.herokuapp.com/api/token?length=15
Mam nadzieję, że to pomoże.
źródło
Możesz użyć UUID (uniwersalnie unikalny identyfikator), można go użyć do dowolnego celu, od ciągu uwierzytelniającego użytkownika do identyfikatora transakcji płatniczej.
UUID to liczba 16-oktetowa (128-bitowa). W swojej postaci kanonicznej UUID jest reprezentowany przez 32 cyfry szesnastkowe, wyświetlane w pięciu grupach oddzielonych łącznikami, w postaci 8-4-4-4-12 dla łącznie 36 znaków (32 znaki alfanumeryczne i cztery łączniki).
// wywołanie funkcji
niektóre przykładowe dane wyjściowe będą takie jak:
mam nadzieję, że pomoże komuś w przyszłości :)
źródło
Ta funkcja wygeneruje losowy klucz przy użyciu cyfr i liter:
Przykładowe dane wyjściowe:
źródło
Używam tego jednowarstwowego:
gdzie długość jest długością pożądanego ciągu (podzielny przez 4, w przeciwnym razie zostanie zaokrąglony w dół do najbliższej liczby podzielnej przez 4)
źródło
==
base64url_encode
może być użyty zamiast tego, patrz tutaj: php.net/manual/en/function.base64-encode.phpUżyj poniższego kodu, aby wygenerować losową liczbę 11 znaków lub zmień liczbę zgodnie z wymaganiami.
lub możemy użyć funkcji niestandardowej do wygenerowania liczby losowej
źródło
substr(str_shuffle(str_repeat('0123456789abcdefghijklmnopqrstvwxyz', 36)), 0, 11);
np. (w pseudo kodzie)
źródło
Oto najlepszy unikalny generator identyfikatorów dla Ciebie. zrobione przeze mnie.
możesz powtórzyć dowolne „var” dla swojego identyfikatora, jak chcesz. ale $ mdun jest lepszy, możesz zamienić md5 na sha1, aby uzyskać lepszy kod, ale będzie on bardzo długi, co może nie być potrzebne.
Dziękuję Ci.
źródło
Do naprawdę losowych ciągów możesz użyć
wyjścia:
więc nawet jeśli spróbujesz wygenerować ciąg wiele razy dokładnie w tym samym czasie, otrzymasz inną wydajność.
źródło
Podczas próby wygenerowania losowego hasła próbujesz:
Najpierw wygeneruj kryptograficznie bezpieczny zestaw losowych bajtów
Drugi polega na zamianie losowych bajtów w ciąg znaków do wydrukowania
Teraz istnieje wiele sposobów generowania losowych bajtów w php, takich jak:
Następnie chcesz zamienić te losowe bajty na ciąg znaków do wydrukowania:
Możesz użyć bin2hex :
lub base64_encode :
Pamiętaj jednak, że nie kontrolujesz długości łańcucha, jeśli używasz base64. Aby to zrobić, możesz użyć bin2hex, użycie 32 bajtów zamieni się w ciąg znaków o długości 64 znaków . Ale tak to będzie działać tylko w łańcuchu NAWET .
Zasadniczo możesz po prostu zrobić :
źródło
Oto czego używam:
źródło
źródło
Jest to prosta funkcja, która pozwala generować losowe ciągi znaków zawierające litery i cyfry (alfanumeryczne). Możesz także ograniczyć długość łańcucha. Te losowe ciągi znaków mogą być wykorzystywane do różnych celów, w tym: Kod polecający, Kod promocyjny, Kod kuponu. Funkcja opiera się na następujących funkcjach PHP: base_convert, sha1, uniqid, mt_rand
źródło
po przeczytaniu poprzednich przykładów wpadłem na to:
Powielam 10 razy tablicę [0-9, AZ] i tasuję elementy, po tym jak otrzymam losowy punkt początkowy dla substr (), aby być bardziej „kreatywnym” :) możesz dodać [az] i inne elementy do tablicy, powielić mniej więcej bądź bardziej kreatywny ode mnie
źródło
Podczas korzystania z linków weryfikacyjnych lubię używać kluczy skrótów. Poleciłbym użycie mikrotimu i zaszyfrowanie tego przy użyciu MD5, ponieważ nie powinno być żadnego powodu, dla którego klucze powinny być takie same, ponieważ hashy oparte na mikrotimie.
$key = md5(rand());
$key = md5(microtime());
źródło
powyższa funkcja wygeneruje losowy ciąg znaków o długości 11 znaków.
źródło
Jeśli chcesz wygenerować unikalny ciąg znaków w PHP, spróbuj wykonać następujące czynności.
W tym,
uniqid()
- Wygeneruje unikalny ciąg. Ta funkcja zwraca unikalny identyfikator oparty na sygnaturze czasowej jako ciąg.mt_rand()
- Wygeneruj losową liczbę.md5()
- Wygeneruje ciąg skrótu.źródło
Scott, tak, bardzo piszesz i dobre rozwiązanie! Dzięki.
Muszę również wygenerować unikalny token API dla każdego użytkownika. Oto moje podejście, wykorzystałem informacje o użytkowniku (identyfikator użytkownika i nazwa użytkownika):
Proszę spojrzeć i dać mi znać, czy mogę coś ulepszyć. Dzięki
źródło
Oto, czego używam w jednym z moich projektów, działa świetnie i generuje UNIKALNY RÓŻOWY TOKEN :
Pamiętaj, że pomnożyłem znacznik czasu przez trzy, aby wprowadzić zamieszanie dla każdego, kto może zastanawiać się, jak wygenerowany jest ten token;)
Mam nadzieję, że to pomoże :)
źródło
Myślę, że to najlepsza metoda do użycia.
źródło
możemy użyć tego dwóch wierszy kodu do wygenerowania unikalnego ciągu, który przetestowano około 10000000 razy iteracji
źródło
Zawsze używam tej funkcji do generowania niestandardowego losowego ciągu alfanumerycznego ... Mam nadzieję, że ta pomoc.
Generuje na przykład: Y1FypdjVbFCFK6Gh9FDJpe6dciwJEfV6MQGpJqAfuijaYSZ86g
Jeśli chcesz porównać z innym ciągiem, aby upewnić się, że jest to unikalna sekwencja, możesz użyć tej sztuczki ...
generuje dwa unikalne ciągi:
qsBDs4JOoVRfFxyLAOGECYIsWvpcpMzAO9pypwxsqPKeAmYLOi
Ti3kE1WfGgTNxQVXtbNNbhhvvapnaUfGMVJecHkUjHbuCb85pF
Mam nadzieję, że tego właśnie szukasz ...
źródło
Prostym rozwiązaniem jest konwersja podstawy 64 na alfanumeryczną poprzez odrzucenie znaków innych niż alfanumeryczne.
Ten używa random_bytes () dla kryptograficznie bezpiecznego wyniku.
źródło
Myślę, że to lepsze rozwiązanie
źródło
Uważam, że problemem wszystkich istniejących pomysłów jest to, że są one prawdopodobnie wyjątkowe, ale nie na pewno wyjątkowe (jak wskazano w odpowiedzi Dariusza Walczaka na loletech). Mam rozwiązanie, które jest naprawdę wyjątkowe. Wymaga, aby twój skrypt miał jakąś pamięć. Dla mnie jest to baza danych SQL. Możesz także po prostu zapisać gdzieś plik. Istnieją dwie implementacje:
Pierwsza metoda: mają DWA pola zamiast 1, które zapewniają wyjątkowość. Pierwsze pole to numer identyfikacyjny, który nie jest losowy, ale jest unikalny (pierwszy identyfikator to 1, drugi 2 ...). Jeśli używasz SQL, po prostu zdefiniuj pole ID za pomocą właściwości AUTO_INCREMENT. Drugie pole nie jest unikalne, ale jest losowe. Można to wygenerować za pomocą dowolnej innej techniki, o której wspominali ludzie. Pomysł Scotta był dobry, ale md5 jest wygodny i prawdopodobnie wystarczający do większości celów:
Druga metoda: Zasadniczo ten sam pomysł, ale początkowo wybierz maksymalną liczbę ciągów, które kiedykolwiek zostaną wygenerowane. To może być naprawdę duża liczba jak bilion. Następnie zrób to samo, wygeneruj identyfikator, ale zeruj go, aby wszystkie identyfikatory miały tę samą liczbę cyfr. Następnie po prostu połącz identyfikator z losowym ciągiem. Dla większości celów będzie wystarczająco losowy, ale sekcja ID zapewni, że będzie on również unikalny.
źródło
Możesz użyć tego kodu, mam nadzieję, że będzie on dla ciebie pomocny.
Szczegóły na temat generatora kodów losowych w PHP
źródło
Uproszczenie powyższego kodu Scotts poprzez usunięcie niepotrzebnych pętli, które bardzo spowalnia i nie czyni go bardziej bezpiecznym niż wywoływanie openssl_random_pseudo_bytes tylko raz
źródło
openssl
nie powoduje tego, to z powodu błędu modulo w instrukcji return. 100 (zakres) nie dzieli równomiernie 255 (1 bajt) i powoduje te wyniki. Moim największym problemem z twoją odpowiedzią jest to, że stwierdzasz, że funkcja jest tak bezpieczna jak używanie pętli, co jest fałszem. Twoja implementacja crypto_rand_secure nie jest kryptograficznie bezpieczna i wprowadza w błąd.openssl
bezpieczniejszej, ale co ważniejsze, nie czyni jej mniej bezpieczną, ta odpowiedź robi. Powyższy kod przyjmuje całkowicie dobrą liczbę losową i zmienia ją, przesuwając w kierunku niższych liczb. Jeśli umieścisz zastrzeżenie w odpowiedzi, stwierdzając, że jest ono szybsze (poprzez usunięcie pętli), ale nie jest to CSPRNG, rozwiązałoby to ten problem. Z miłości do kryptografii proszę poinformować użytkowników, że wyniki tej funkcji mogą być stronnicze i nie jest równoważnym rozwiązaniem. Pętla jest nie tylko po to, aby cię drażnić.