Así que he estado investigando un poco y he estado tratando de reconstruir una función que genere un UUID v4 válido en PHP. Esto es lo más cerca que he podido llegar. Mi conocimiento en hexadecimal, decimal, binario, operadores bit a bit de PHP y similares es casi inexistente. Esta función genera un UUID v4 válido hasta un área. Un v4 UUID debe tener la forma de:
xxxxxxxx-xxxx- 4 xxx- y xxx-xxxxxxxxxxxx
donde y es 8, 9, A o B. Aquí es donde las funciones fallan, ya que no se adhiere a eso.
Esperaba que alguien con más conocimiento que yo en esta área pudiera echarme una mano y ayudarme a arreglar esta función para que se adhiera a esa regla.
La función es la siguiente:
<?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;
}
?>
Gracias a cualquiera que pueda ayudarme.
$newId = exec('uuidgen -r');
Respuestas:
Tomado de este comentario en el manual de PHP, podría usar esto:
fuente
En lugar de dividirlo en campos individuales, es más fácil generar un bloque aleatorio de datos y cambiar las posiciones de los bytes individuales. También debe usar un generador de números aleatorios mejor que mt_rand ().
De acuerdo con RFC 4122 - Sección 4.4 , debe cambiar estos campos:
time_hi_and_version
(bits 4-7 del séptimo octeto),clock_seq_hi_and_reserved
(bit 6 y 7 del noveno octeto)Todos los otros 122 bits deben ser suficientemente aleatorios.
El siguiente enfoque genera 128 bits de datos aleatorios utilizando
openssl_random_pseudo_bytes()
, realiza las permutaciones en los octetos y luego utilizabin2hex()
y realizavsprintf()
el formateo final.Con PHP 7, generar secuencias de bytes al azar es aún más simple usando
random_bytes()
:fuente
$data = file_get_contents('/dev/urandom', NULL, NULL, 0, 16);
$data = $data ?? random_bytes( 16 );
ahora PUEDE especificar su propia fuente de datos aleatoria, o dejar que la función lo haga por usted. :-)Cualquiera que use dependencias del compositor , puede considerar esta biblioteca: https://github.com/ramsey/uuid
No hay nada más fácil que esto:
fuente
en sistemas unix, use el núcleo del sistema para generar un uuid para usted.
Crédito Samveen en https://serverfault.com/a/529319/210994
fuente
/dev/random
que bloquea si se agota el grupo de entropía./dev/urandom
cómo hacer este origen de archivo de núcleo especial , que a mi entender no se agotaría, pero corre el riesgo de devolver uuids duplicados. Supongo que es una compensación; ¿Realmente necesitas una identificación única influenciada por la entropía del sistema?En mi búsqueda de crear un v4 uuid, llegué primero a esta página, luego encontré esto en http://php.net/manual/en/function.com-create-guid.php
crédito: pavel.volyntsev
Editar: para aclarar, esta función siempre le dará un uuid v4 (PHP> = 5.3.0).
Cuando la función com_create_guid está disponible (generalmente solo en Windows), la usará y eliminará las llaves.
Si no está presente (Linux), recurrirá a esta función fuerte openssl_random_pseudo_bytes aleatoria, luego utilizará vsprintf para formatearla en v4 uuid.
fuente
Mi respuesta se basa en un comentario de usuario uniqid pero usa la función openssl_random_pseudo_bytes para generar cadenas aleatorias en lugar de leer
/dev/urandom
fuente
Si lo usa
CakePHP
, puede usar su métodoCakeText::uuid();
de la clase CakeText para generar un uuid RFC4122.fuente
Una ligera variación en la respuesta de Jack para agregar soporte para PHP <7:
fuente
Inspirado por la respuesta de broofa aquí .
O si no puede utilizar funciones anónimas.
fuente
mt_rand()
que no se garantiza el azar.Después de buscar exactamente lo mismo y casi implementar una versión de esto yo mismo, pensé que valía la pena mencionar que, si lo estás haciendo dentro de un marco de WordPress , WP tiene su propia función súper práctica para exactamente esto:
$myUUID = wp_generate_uuid4();
Puedes leer la descripción y la fuente aquí .
fuente
false
🤷¿Qué tal si usas mysql para generar el uuid por ti?
fuente
UUID()
función de MySQL crea v1 uuids.fuente
De tom, en http://www.php.net/manual/en/function.uniqid.php
fuente
/dev/urandom
debe estar bien,/dev/random
solo debe usarse para generar claves criptográficas a largo plazo.mt_rand()
si no hay nada más elegante disponible.random_bytes()
en PHP 7 y listo :-)Estoy seguro de que hay una forma más elegante de hacer la conversión de binario a decimal para las porciones
4xxx
yyxxx
. Pero si quieres usarloopenssl_random_pseudo_bytes
como tu generador de números criptográficamente seguro, esto es lo que yo uso:fuente
Utilice Symfony Polyfill / Uuid.
Luego puede generar uuid como función php nativa:
Más información al respecto, lea en la publicación oficial de blop de Symfony: https://symfony.com/blog/introducing-the-new-symfony-uuid-polyfill
fuente