También disponible en: English · Português · Français · العربية
Generador y decodificador de ULID
Identificadores ordenables con marca de tiempo: monótonos por defecto y decodificados con las comprobaciones que casi todos se saltan.
¿Qué es un ULID?
Un ULID es un identificador de 26 caracteres que lleva dentro la hora a la que se creó. Los 10 primeros caracteres son una cuenta de 48 bits de milisegundos desde 1970; los 16 restantes son 80 bits de aleatoriedad. Las dos mitades se escriben en el base32 de Crockford, un alfabeto con los diez dígitos y veintidós letras que deja fuera la I, la L, la O y la U precisamente porque son las que se leen mal.
La gracia de poner el reloj delante es que ordenar el texto ordena por fecha. Un UUID versión 4 es puro azar, así que una tabla indexada por uno de ellos reparte sus escrituras por todo el índice; los identificadores que crecen con el tiempo mantienen juntas las filas nuevas. Ese mismo razonamiento está detrás del UUID versión 7, que el RFC 9562 estandarizó en 2024 y que es la mejor opción si puedes usarlo: el ULID llegó antes, no es un estándar del IETF y merece la pena conocerlo sobre todo porque mucho software ya lo emite.
El formato también encaja donde un UUID no cabe. Son 26 caracteres frente a 36, sin guiones, indiferente a mayúsculas, y aguanta mucho mejor que el hexadecimal que alguien lo dicte o lo copie a mano de una pantalla.
Cómo usarlo
- Elige cuántos necesitas y cópialos. Hasta cien de una vez, sacados de la fuente criptográfica de azar de tu navegador. Copia uno suelto o el lote entero como líneas.
- Deja marcada la casilla de orden salvo que sepas que la quieres quitar. Hace que los identificadores creados en el mismo milisegundo vayan hacia arriba en lugar de sortearse por separado, que es lo que consigue que un lote quede ordenado como se creó.
- Pega cualquier ULID en la segunda casilla para leerlo. Verás el instante en que se creó en tu propia zona horaria, la mitad aleatoria, la forma canónica y los mismos bits escritos en hexadecimal.
Tres cosas que las demás herramientas de ULID hacen mal
La primera es que un lote de ULID casi nunca está ordenado. Veintiséis caracteres en base32 solo quedan en orden si los valores que hay detrás crecen, y dos identificadores creados en el mismo milisegundo comparten marca de tiempo, así que su orden lo decide la mitad aleatoria. Dos sorteos independientes son igual de probables en un sentido que en otro, o sea que es una moneda al aire por construcción y no un fallo ocasional; y eso es justo lo que sale al medirlo. Con 20.000 llamadas dentro de un mismo milisegundo, el porcentaje en orden equivocado fue del 49,9, el 49,6 y el 50,2 por ciento para tres flujos de azar distintos, y del 49,6 y el 50,1 por ciento en dos pasadas contra la implementación de referencia de JavaScript en tiempo real. Su fábrica monótona los deja todos en cero. Como la ordenación es la razón entera para preferir este formato, aquí está activada por defecto y es una casilla, no una suposición.
La segunda es el desbordamiento. Veintiséis caracteres base32 guardan 130 bits y un ULID son 128, así que el primer carácter solo puede ir del 0 al 7: el mayor ULID posible es 7ZZZZZZZZZZZZZZZZZZZZZZZZZ. La especificación dice que cualquier intento de decodificar uno mayor debe rechazarse en todas las implementaciones, precisamente para evitar errores de desbordamiento. Probando los treinta y dos primeros caracteres posibles contra la implementación de referencia, su validador devuelve verdadero con todos mientras su propio decodificador lanza un error con veinticuatro: tres cuartas partes de las cadenas que llama válidas no son ULID. Aquí ese caso tiene veredicto propio en vez de pasar de largo.
La tercera es la transcripción. Crockford diseñó este alfabeto para que las letras excluidas se pudieran recuperar al leer: la I y la L se decodifican como 1, la O como 0 y las mayúsculas dan igual. La implementación de referencia rechaza las tres y trae aparte una función de reparación que tienes que llamar tú, así que un ULID copiado de una captura falla sin ningún motivo. Esta herramienta las resuelve y te avisa de que lo ha hecho, que no es lo mismo que resolverlas en silencio.
Límites honestos
La marca de tiempo vale lo que valga el reloj de la máquina que generó el identificador. Un ULID dice cuándo creía esa máquina que era; en un aparato con la hora mal, o que retrocedió por un segundo intercalar o una corrección de NTP, el valor es falso y el formato no guarda ninguna señal de ello. La ordenación es una comodidad, no una auditoría.
La mitad aleatoria no es una firma. Cualquiera puede generar un identificador con la marca de tiempo que le apetezca: el formato no tiene secreto ni suma de verificación, así que un ULID no demuestra nada sobre quién lo hizo ni cuándo. Trátalo como un nombre, nunca como una prueba.
La conversión de ULID a UUID que ofrecen todas las herramientas es exacta, pero el resultado no es un UUID. Son los mismos 128 bits escritos en hexadecimal, y un UUID reserva cuatro bits para el número de versión y dos para la variante, de los que la parte aleatoria de un ULID no sabe nada. Aproximadamente uno de cada sesenta y cuatro cae por casualidad en valores que pasarían por un UUID versión 4; el resto son cadenas hexadecimales con forma de UUID que ningún analizador conforme aceptará. Esta página enseña el hexadecimal y te dice en qué caso estás.
Por último, el orden monótono es por generador, no global. Dos servidores generando en el mismo milisegundo se entrelazarán según caigan sus mitades aleatorias, y nada los coordina. Dentro de una pestaña, un proceso o un pool de conexiones el orden se mantiene; entre máquinas, no.
¿Por qué es gratis?
Todo ocurre en tu navegador. Los bits aleatorios salen de tu propia fuente criptográfica, el reloj es el tuyo y ningún identificador se envía a ninguna parte, lo que aquí importa más de lo normal: un identificador que ha visto un servidor ya no es del todo tuyo para usarlo como testigo.
No hay cuenta, ni límite, ni marca de agua, porque no hay coste de servidor que recuperar.