Robiłem więc kopanie i próbowałem poskładać funkcję, która generuje prawidłowy UUID v4 w PHP. To jest najbliższy czas jaki mogłem przyjść. Moja wiedza na temat szesnastkowych, dziesiętnych, binarnych, bitowych operatorów PHP i tym podobnych prawie nie istnieje. Ta funkcja generuje prawidłowy identyfikator UUID v4 aż do jednego obszaru. UUID v4 powinien mieć postać:
xxxxxxxx-xxxx- 4 xxx- Y XXX-XXXXXXXXXXXX
gdzie y wynosi 8, 9, A lub B. To jest, gdzie funkcje zawodzą, ponieważ nie spełniają tego.
Miałem nadzieję, że ktoś z większą wiedzą niż ja w tej dziedzinie może mi pomóc i naprawić tę funkcję, aby była zgodna z tą regułą.
Funkcja jest następująca:
<?php
function gen_uuid() {
$uuid = array(
'time_low' => 0,
'time_mid' => 0,
'time_hi' => 0,
'clock_seq_hi' => 0,
'clock_seq_low' => 0,
'node' => array()
);
$uuid['time_low'] = mt_rand(0, 0xffff) + (mt_rand(0, 0xffff) << 16);
$uuid['time_mid'] = mt_rand(0, 0xffff);
$uuid['time_hi'] = (4 << 12) | (mt_rand(0, 0x1000));
$uuid['clock_seq_hi'] = (1 << 7) | (mt_rand(0, 128));
$uuid['clock_seq_low'] = mt_rand(0, 255);
for ($i = 0; $i < 6; $i++) {
$uuid['node'][$i] = mt_rand(0, 255);
}
$uuid = sprintf('%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x',
$uuid['time_low'],
$uuid['time_mid'],
$uuid['time_hi'],
$uuid['clock_seq_hi'],
$uuid['clock_seq_low'],
$uuid['node'][0],
$uuid['node'][1],
$uuid['node'][2],
$uuid['node'][3],
$uuid['node'][4],
$uuid['node'][5]
);
return $uuid;
}
?>
Dziękujemy wszystkim, którzy mogą mi pomóc.
$newId = exec('uuidgen -r');
Odpowiedzi:
Na podstawie tego komentarza do instrukcji PHP możesz użyć tego:
źródło
Zamiast podziału na poszczególne pola łatwiej jest wygenerować losowy blok danych i zmienić pozycje poszczególnych bajtów. Powinieneś także użyć lepszego generatora liczb losowych niż mt_rand ().
Zgodnie z RFC 4122 - sekcja 4.4 , musisz zmienić te pola:
time_hi_and_version
(bity 4-7 z 7 oktetu),clock_seq_hi_and_reserved
(bit 6 i 7 z 9 oktetu)Wszystkie pozostałe 122 bity powinny być wystarczająco losowe.
Poniższe podejście generuje 128 bitów losowych danych przy użyciu
openssl_random_pseudo_bytes()
, dokonuje permutacji w oktetach, a następnie używabin2hex()
ivsprintf()
wykonuje ostateczne formatowanie.W PHP 7 generowanie losowych sekwencji bajtów jest jeszcze prostsze przy użyciu
random_bytes()
:źródło
$data = file_get_contents('/dev/urandom', NULL, NULL, 0, 16);
$data = $data ?? random_bytes( 16 );
Teraz możesz określić własne losowe źródło danych lub pozwolić, aby funkcja zrobiła to za Ciebie. :-)Każdy, kto używa zależności kompozytora , może rozważyć tę bibliotekę: https://github.com/ramsey/uuid
Nie ma nic łatwiejszego niż to:
źródło
w systemach uniksowych użyj jądra systemowego, aby wygenerować dla Ciebie identyfikator UUID.
Kredyty Samveen na https://serverfault.com/a/529319/210994
źródło
/dev/random
blokuje się, jeśli pula entropii zostanie wyczerpana./dev/urandom
, które w moim rozumieniu nie wyczerpałoby się, ale ryzykuje zwrot zduplikowanych plików UUID. Myślę, że to kompromis; czy naprawdę potrzebujesz unikalnego identyfikatora pod wpływem entropii systemu?Poszukując utworzenia identyfikatora użytkownika v4, najpierw znalazłem się na tej stronie, a potem znalazłem to na stronie http://php.net/manual/en/function.com-create-guid.php
kredyt: pavel.volyntsev
Edycja: aby wyjaśnić, ta funkcja zawsze da ci identyfikator użytkownika v4 (PHP> = 5.3.0).
Gdy funkcja com_create_guid jest dostępna (zwykle tylko w systemie Windows), użyje jej i usunie nawiasy klamrowe.
Jeśli nie jest obecny (Linux), powróci do tej silnej losowej funkcji openssl_random_pseudo_bytes, a następnie użyje vsprintf do sformatowania go w UUID v4.
źródło
Moja odpowiedź opiera się na komentarzu uniqid komentarza użytkownika, ale używa funkcji openssl_random_pseudo_bytes do generowania losowego ciągu zamiast czytania z
/dev/urandom
źródło
Jeśli używasz
CakePHP
, możesz użyć ich metodyCakeText::uuid();
z klasy CakeText, aby wygenerować identyfikator użytkownika RFC4122.źródło
Niewielka różnica w odpowiedzi Jacka, aby dodać obsługę PHP <7:
źródło
Zainspirowany broofa odpowiedź jest tutaj .
Lub jeśli nie możesz korzystać z anonimowych funkcji.
źródło
mt_rand()
nie ma gwarancji losowości.Po wyszukaniu dokładnie tej samej rzeczy i prawie zaimplementowaniu jej osobiście, pomyślałem, że warto wspomnieć, że jeśli robisz to w ramach WordPress , WP ma własną super przydatną funkcję:
$myUUID = wp_generate_uuid4();
Możesz przeczytać opis i źródło tutaj .
źródło
false
drugąCo powiesz na użycie mysql do wygenerowania UUID?
źródło
UUID()
Funkcja MySQL tworzy uuids v1.źródło
Od Toma na http://www.php.net/manual/en/function.uniqid.php
źródło
/dev/urandom
powinno być w porządku -/dev/random
powinno być używane tylko do generowania długoterminowych kluczy kryptograficznych.mt_rand()
jeśli nic bardziej wymyślnego nie jest dostępne.random_bytes()
w PHP 7 i gotowe :-)Jestem pewien, że istnieje bardziej elegancki sposób na konwersję z binarnej na dziesiętną dla części
4xxx
iyxxx
. Ale jeśli chcesz używaćopenssl_random_pseudo_bytes
swojego kryptograficznie bezpiecznego generatora liczb, używam tego:źródło
Użyj Symfony Polyfill / Uuid
Następnie możesz po prostu wygenerować uuid jako natywną funkcję php:
Więcej informacji na ten temat można znaleźć w oficjalnym poście na Symfony - https://symfony.com/blog/introducing-the-new-symfony-uuid-polyfill
źródło