Próbuję utworzyć losowy ciąg w PHP i nie otrzymuję absolutnie żadnych danych wyjściowych z tym:
<?php
function RandomString()
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randstring = '';
for ($i = 0; $i < 10; $i++) {
$randstring = $characters[rand(0, strlen($characters))];
}
return $randstring;
}
RandomString();
echo $randstring;
Co ja robię źle?
strlen($characters)
=>strlen($characters) - 1
- długość łańcucha zaczyna się od 1Odpowiedzi:
Aby odpowiedzieć konkretnie na to pytanie, dwa problemy:
$randstring
nie jest objęty zakresem, gdy go echo.Oto fragment kodu z poprawkami:
Wypisz losowy ciąg za pomocą wywołania poniżej:
źródło
substr(str_shuffle(MD5(microtime())), 0, 10);
?rand()
namt_rand()
. Kiedyś metodę i przeżył mnóstwo kolizji z nazwami.Jeszcze jeden sposób.
AKTUALIZACJA (teraz generuje dowolną długość łańcucha):
Otóż to. :)
źródło
Istnieje wiele odpowiedzi na to pytanie, ale żadna z nich nie wykorzystuje kryptograficznie bezpiecznego generatora liczb pseudolosowych (CSPRNG).
Prostą, bezpieczną i poprawną odpowiedzią jest użycie RandomLib i nie wymyślanie koła na nowo.
Dla tych z was, którzy nalegają na wymyślenie własnego rozwiązania, PHP 7.0.0 zapewni
random_int()
w tym celu; jeśli nadal korzystasz z PHP 5.x, napisaliśmy polifill dla PHP 5random_int()
, abyś mógł korzystać z nowego API nawet przed uaktualnieniem do PHP 7.Bezpieczne generowanie losowych liczb całkowitych w PHP nie jest łatwym zadaniem. Zawsze powinieneś skonsultować się z ekspertami w dziedzinie kryptografii StackExchange przed wdrożeniem domowego algorytmu w produkcji.
Dzięki bezpiecznemu generatorowi liczb całkowitych generowanie losowego ciągu za pomocą CSPRNG jest spacerkiem po parku.
Tworzenie bezpiecznego, losowego ciągu
Zastosowanie :
Demo : https://3v4l.org/IMJGF (Zignoruj awarie PHP 5; wymaga random_compat)
źródło
$keyspace = str_shuffle($keyspace );
dla większego bezpieczeństwarandom_int()
zamiastrand()
lubmt_rand()
nie dodaje złożoności programistom. Jednocześnie zapewnia im większe bezpieczeństwo. Ludzie, którzy przychodzą do StackOverflow w poszukiwaniu szybkich rozwiązań, mogą nie wiedzieć, czy budowana przez nich rzecz musi być bezpieczna, czy nie. Jeśli udzielimy im domyślnie bezpiecznych odpowiedzi, stworzą bezpieczniejszy Internet, nawet jeśli z ich perspektywy jest to całkowicie przypadkowe. Dlaczego miałbyś sprzeciwić się temu celowi, jest dla mnie tajemnicą.Spowoduje to utworzenie ciągu szesnastkowego o długości 20 znaków:
W PHP 7 ( random_bytes () ):
źródło
openssl_random_pseudo_bytes()
nie używał silnego algorytmu kryptograficznego aż do php 5.6. Powiązany błąd: bugs.php.net/bug.php?id=70014openssl_random_pseudo_bytes()
, nic nie otrzymasz. Zauważ też, że podczas używania,bin2hex(openssl_random_pseudo_bytes($length / 2))
ponieważ pracujesz z liczbami całkowitymi, automatycznie usunie to modulo i użyje następnej najniższej wielokrotności 2. Tak więc,$length = 19
wygeneruje ciąg długości 18.fgets($fp, 1024)
i każdy edytor plików, który ma problemy z bardzo długich linii:function string_rand($len, $split="\n") { return substr(chunk_split(bin2hex(openssl_random_pseudo_bytes(ceil($len / 2))), 1023, $split), 0, $len); }
Zestaw$split
donull
czy powinien wrócić do jednego-liner. Dzięki temu możesz używać go w obu przypadkach.$string = substr(base64_encode(random_bytes($size)), 0, $size);
@tasmaniski: twoja odpowiedź zadziałała dla mnie. Miałem ten sam problem i sugerowałbym go tym, którzy kiedykolwiek szukają tej samej odpowiedzi. Oto z @tasmaniski:
Oto film z YouTube pokazujący, jak utworzyć losową liczbę
źródło
md5
że spowoduje to ograniczenie do 30 znaków i zawsze małe litery.md5(rand())
oferuje tylko 2 ^ 32 możliwe wartości. Oznacza to, że po średnio 2 ^ 16 losowych ciągach będziesz oczekiwać, że jeden się powtórzy.W zależności od aplikacji (chciałem generować hasła) możesz użyć
Będąc base64, mogą zawierać
=
lub-
żądane znaki. Możesz wygenerować dłuższy ciąg, a następnie filtrować i przycinać go, aby je usunąć.openssl_random_pseudo_bytes
wydaje się być zalecanym sposobem na wygenerowanie odpowiedniej liczby losowej w php. Dlaczegorand
nie używa?/dev/random
Nie wiem.źródło
openssl_random_pseudo_bytes()
jest przenośny.Oto prosty jednowierszowy, który generuje prawdziwy losowy ciąg bez zapętlania poziomu skryptu lub korzystania z bibliotek OpenSSL.
Aby go rozbić, aby parametry były jasne
Ta metoda polega na losowym powtarzaniu listy znaków, a następnie tasuje połączony ciąg znaków i zwraca określoną liczbę znaków.
Możesz dalej losować to, losując długość zwracanego ciągu, zastępując
$chrRandomLength
gomt_rand(8, 15)
(dla losowego ciągu od 8 do 15 znaków).źródło
$chrRepeatMax
i$chrRepeatMin
) - więc ciąg znaków 10, może (mało prawdopodobne, ale możliwe) być „aaaaaaaaaa”.Tada!
źródło
sha1
że spowoduje to ograniczenie do 40 znaków i zawsze małe litery.rant()
bycia losowym nie ma znaczenia, gdy sha nie jest równomiernie rozłożona. Jeśli wybierzesz losowo z nierównej dystrybucji, otrzymasz dokładnie taką samą nierównomierną dystrybucję. Podkreślam, że nie jest to przypadkowość „poziomu kryptograficznego”, gdyby tak było, nie powinieneś używaćrand()
żadnego z nich. Wyrywanie z równomiernego rozkładu, jak w zaakceptowanej odpowiedzi, wymaga minimalnego wysiłku i jest tak losowe, jak rand (), co jest rozsądne.Lepszym sposobem na wdrożenie tej funkcji jest:
mt_rand
jest bardziej losowy zgodnie z tym i tym w PHP 7.rand
Funkcja jest aliasemmt_rand
.źródło
mt_rand
nie generuje bezpiecznych kryptograficznie wartości. Do tego należy użyć PHP7random_int
lubrandom_bytes
.$randstring
zakres funkcji nie jest taki sam jak zakres, w którym go wywołujesz. Musisz przypisać wartość zwracaną do zmiennej.Lub po prostu echo zwracanej wartości:
Również w swojej funkcji masz mały błąd. W pętli for należy użyć,
.=
aby każdy znak był dołączany do ciągu. Korzystając z niego=
, zastępujesz go każdą nową postacią zamiast dodawać.źródło
Najpierw określ alfabet, którego chcesz użyć:
Następnie użyj
openssl_random_pseudo_bytes()
do wygenerowania odpowiednich danych losowych:Wreszcie, wykorzystujesz te losowe dane, aby utworzyć hasło. Ponieważ każdy znak
$random
może byćchr(0)
dochr(255)
, kod używa reszty po podzieleniu jego wartości porządkowej,$alphabet_length
aby upewnić się, że wybierane są tylko znaki z alfabetu (pamiętaj, że w ten sposób wpływa to na losowość):Alternatywnie i ogólnie lepiej jest użyć RandomLib i SecurityLib :
źródło
%
spowoduje stronnicze wyjście. Jednak silne +1 dla RandomLib. Nie wymyślaj koła ponownie.Krótkie metody ..
Oto kilka najkrótszych metod generowania losowego ciągu
źródło
Testowałem tam wydajność najpopularniejszych funkcji, czas potrzebny do wygenerowania 1 000 000 ciągów 32 symboli na moim urządzeniu to:
Należy pamiętać, że nie jest ważne, jak naprawdę to było, ale które jest wolniejsze, a które jest szybsze, dzięki czemu można wybrać zgodnie z wymaganiami, w tym gotowość do kryptografii itp.
substr () wokół MD5 został dodany ze względu na dokładność, jeśli potrzebujesz łańcucha, który jest krótszy niż 32 symbole.
W odpowiedzi: ciąg nie został połączony, ale nadpisany, a wynik funkcji nie został zapisany.
źródło
PHP 7+ Generuj kryptograficznie bezpieczne losowe bajty za pomocą funkcji random_bytes .
Możliwe wyjście
PHP 5.3+ Generuj pseudolosowe bajty za pomocą funkcji openssl_random_pseudo_bytes .
Możliwe wyjście
Najlepszy przypadek użycia może być
Możliwe wyjście
źródło
Jednym bardzo szybkim sposobem jest zrobienie czegoś takiego:
To wygeneruje losowy ciąg o długości 10 znaków. Oczywiście, niektórzy mogą powiedzieć, że jest nieco bardziej obciążony po stronie obliczeniowej, ale obecnie procesory są zoptymalizowane do szybkiego uruchamiania algorytmu md5 lub sha256. I oczywiście, jeśli
rand()
funkcja zwróci tę samą wartość, wynik będzie taki sam, z szansą 1/32767 na bycie takim samym. Jeśli problemem są zabezpieczenia, po prostu zmieńrand()
namt_rand()
źródło
źródło
Ten został pobrany ze źródeł administratora :
Administrator , narzędzie do zarządzania bazami danych napisane w PHP.
źródło
Funkcja pomocnicza z frameworka Laravel 5
źródło
Źródło: http://www.xeweb.net/2011/02/11/generate-a-random-string-az-0-9-in-php/
źródło
Zmodyfikowana wersja funkcji działa dobrze, ale znalazłem tylko jeden problem: użyłeś niewłaściwego znaku do umieszczenia znaków $, więc znak „jest czasem częścią generowanego ciągu losowego.
Aby to naprawić, zmień:
do:
W ten sposób używane są tylko zamknięte znaki, a znak „nigdy nie będzie częścią generowanego ciągu losowego.
źródło
Kolejna linijka, która generuje losowy ciąg 10 znaków z literami i cyframi. Utworzy tablicę za pomocą
range
(dostosuje drugi parametr, aby ustawić rozmiar), zapętli tę tablicę i przypisze losowy znak ASCII (zakres 0-9 lub az), a następnie wszczepi tablicę w celu uzyskania łańcucha.Uwaga: działa to tylko w PHP 5.3 i nowszych
źródło
rand(0, 57-48+122-97)<57-48?...:...
? :)Jedna wkładka.
Jest szybki dla ogromnych strun z pewną wyjątkowością.
źródło
md5(rand())
to strasznie niepewny sposób generowania losowej liczby.Od php7 istnieją funkcje random_bytes. https://www.php.net/manual/ru/function.random-bytes.php Abyś mógł wygenerować taki ciąg losowy
źródło
Podobał mi się ostatni komentarz, który używał openssl_random_pseudo_bytes, ale nie było to dla mnie rozwiązaniem, ponieważ wciąż musiałem usuwać znaki, których nie chciałem, i nie byłem w stanie uzyskać łańcucha o ustalonej długości. Oto moje rozwiązanie ...
źródło
źródło
Oto moje proste jednoliniowe rozwiązanie do generowania przyjaznego losowego hasła, z wyłączeniem znaków, które wyglądają podobnie, jak „1” i „l”, „O” i „0” itd.… Tutaj jest 5 znaków, ale możesz łatwo zmień to oczywiście:
źródło
Oto inne rozwiązanie.
PS. Używam PHP 7.2 na Ubuntu.
źródło
Innym sposobem generowania losowego ciągu w PHP jest:
źródło
Oto jak to zrobić, aby uzyskać prawdziwy unikalny losowy klucz:
Możesz użyć time (), ponieważ jest to uniksowy znacznik czasu i zawsze jest unikalny w porównaniu z innymi losowymi wymienionymi powyżej. Następnie możesz wygenerować sumę md5 i pobrać żądaną długość z wygenerowanego MD5 ciągu . W tym przypadku używam 10 znaków i mógłbym użyć dłuższego łańcucha, jeśli chciałbym, aby był bardziej unikalny.
Mam nadzieję, że to pomoże.
źródło
time()
jest daleki od unikalności: będzie zwracał tę samą wartość raz za razem, aż skończy się bieżąca sekunda. To, co naprawdę zapewnia pewną losowość, tostr_shuffle()
reszta kodu ogranicza tylko próbkę do wybierania znaków.time()
(to tylko znacznik czasu), jest to słabe źródło losowości.Sparametryzowany jednowierszowy, wykorzystujący tylko natywne funkcje PHP , działający od PHP 5.1.0
źródło