Un UUID (identificador único universal o universally unique identifier) es un número de 16 bytes (32 dígitos hexadecimales), referenciado habitualmente mediante cinco grupos separados por guiones 8-4-4-4-12, lo que genera un total de 36 caracteres (32 dígitos y 4 guiones), que se encuentra estandarizado en el RFC 4122.
Se puede usar en múltiples ámbitos: claves primarias en tablas de bases de datos relacionales, identificación única de objetos, componentes,…
Para poder usarlo en un proyecto generado con Laravel dispongo de la librería ramsey/uuid, que se instala como dependencia de Laravel, y que permite generar UUID de tipo 1, 3, 4, y 5, de acuerdo con el RFC 4122. En esta artículo voy a explicar las características de cada tipo de UUID y cómo se generan el Laravel usando la librería mencionada.
Para ello creo un proyecto
$ composer create-project laravel/laravel --prefer-dist uuid-tests
Y un comando para poder hacer pruebas
$ php artisan make:command --command=uuid:test UuidTestCommand
Creo la funcionalidad básica del comando, que me permite especificar el tipo de UUID que quiero computar y el número de veces que voy a hacerlo. El código fuente de este proyecto está disponible en este enlace.
<?php namespace App\Console\Commands; use Illuminate\Console\Command; use Ramsey\Uuid\Uuid; class UuidTestCommand extends Command { /** * Tipo de UUID que se va a calcular * * @var int */ protected $tipoUuid; /** * Número de UUID que se van a calcular * * @var int */ protected $numeroEjecuciones; /** * The name and signature of the console command. * * @var string */ protected $signature = 'uuid:test {tipoUuid=1} {numeroEjecuciones=10}'; /** * The console command description. * * @var string */ protected $description = 'Calcula varias veces (10 por defecto) un UUID del tipo 1, 3, 4 y 5 (1 por defecto)'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { $this->tipoUuid = $this->argument('tipoUuid'); $this->numeroEjecuciones = $this->argument('numeroEjecuciones'); switch ($this->tipoUuid) { case 1: for ($i = 1; $i <= $this->numeroEjecuciones; $i++) { $uuid = Uuid::uuid1(); echo $uuid->toString() . "\n"; } break; case 3: for ($i = 1; $i <= $this->numeroEjecuciones; $i++) { $uuid = Uuid::uuid3(Uuid::NAMESPACE_DNS, 'test.test'); echo $uuid->toString() . "\n"; } break; case 4: for ($i = 1; $i <= $this->numeroEjecuciones; $i++) { $uuid = Uuid::uuid4(); echo $uuid->toString() . "\n"; } break; case 5: for ($i = 1; $i <= $this->numeroEjecuciones; $i++) { $uuid = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'test.test'); echo $uuid->toString() . "\n"; } break; default: $this->alert('Tipo de UUID incorrecto'); } } }
A continuación describo los distintos tipos de UUID y cómo se generan en Laravel.
Table of Contents
Tipos de UUID
Tipo 1
Este tipo de UUID se genera usando una combinación de la dirección MAC del equipo y la fecha y hora actual. Además se añade un componente aleatorio para asegurar que es único. Si ejecuto el comando 5 veces tengo una parte fija, que depende del equipo, y una parte variable, que depende de la fecha y hora actuales y del componente aleatorio.
$ php artisan uuid:test 1 5 c389feae-db71-11e8-87fe-0800271fd0eb c38b2e82-db71-11e8-91fc-0800271fd0eb c38b2f5e-db71-11e8-acaf-0800271fd0eb c38b2fea-db71-11e8-b09f-0800271fd0eb c38b3062-db71-11e8-8f6f-0800271fd0eb
En Laravel se genera mediante
$uuid = Uuid::uuid1();
Tipo 3 y 5
Estos 2 tipos se generan mediante el hashing de una namespace y de un nombre. La diferencia es que la versión 3 usa MD5 como algoritmo de hashing, mientras que la versión 5 usa SHA1.
Si ejecuto el comando 5 veces para el tipo 3 tengo la misma salida en las 5 ejecuciones.
$ php artisan uuid:test 3 5 90ff3dc0-7bbe-3132-9efc-17d6828d50db 90ff3dc0-7bbe-3132-9efc-17d6828d50db 90ff3dc0-7bbe-3132-9efc-17d6828d50db 90ff3dc0-7bbe-3132-9efc-17d6828d50db 90ff3dc0-7bbe-3132-9efc-17d6828d50db
En Laravel se genera mediante
$uuid = Uuid::uuid3(Uuid::NAMESPACE_DNS, 'test.test');
donde
- Uuid::NAMESPACE_DNS es el identificador de namespace, que en este caso es una constante definida en el estándar (un UUID).
- ‘test.test’ es la cadena, que puede ser constante (este caso) o variable, usada para calcular el UUID.
Si ejecuto el comando 5 veces para el tipo 5 tengo la misma salida en las 5 ejecuciones.
$ php artisan uuid:test 5 5 783d51c2-94cd-5e7a-8afe-c2fd6d91f7a2 783d51c2-94cd-5e7a-8afe-c2fd6d91f7a2 783d51c2-94cd-5e7a-8afe-c2fd6d91f7a2 783d51c2-94cd-5e7a-8afe-c2fd6d91f7a2 783d51c2-94cd-5e7a-8afe-c2fd6d91f7a2
En Laravel se genera mediante
$uuid = Uuid::uuid5(Uuid::NAMESPACE_DNS, 'test.test');
Los parámetros son los mismos que en el UUID de tipo 3.
Tipo 4
Este tipo de UUID es completamente aleatorio, por lo que su probabilidad de colisión es mínima, aunque no nula.
$ php artisan uuid:test 4 5 5dad97ba-a7be-4b4d-abba-3a4ff417a402 2e3127c3-c8fb-4764-ba69-b57d13758547 76780e5d-2737-4543-a76a-e8ff0481c2e4 cfe387e5-bf19-470a-b02e-36f83a4471a9 6b7f13ae-8339-4492-a3e2-6dcb3fa345db
En Laravel se genera mediante
$uuid = Uuid::uuid4();
Más info:
- https://en.wikipedia.org/wiki/Universally_unique_identifier
- https://es.wikipedia.org/wiki/Identificador_%C3%BAnico_universal
- https://www.sohamkamani.com/blog/2016/10/05/uuid1-vs-uuid4/