Skip to content

Generar un UUID snippet

El UUIDv4 (122 bits aleatorios) es el identificador por defecto en todas partes.

El UUIDv4 (122 bits aleatorios) es el identificador por defecto en todas partes. La única regla dura: la aleatoriedad debe ser criptográfica — los generadores basados en Math.random o mt_rand son superficie de ataque, porque los IDs adivinables son IDs falsificados. La respuesta de los 2020 para claves de base de datos es la v7: un timestamp de milisegundos de 48 bits antecede a la cola aleatoria, así que las claves se ordenan por tiempo de creación y las inserciones se mantienen mayormente en append en lugar de recorrer la B-tree al azar. C y C++ se omiten: no hay generador en la stdlib.

Receta ejecutable · 13 lenguajesAbrir la herramienta uuid →
Crypto & Encodinguuidrandomidentifierv4v7

Every language

13 lenguajes, copy-ready. One at a time with syntax highlighting, or all inline.

SQLSQLrunnable
SELECT gen_random_uuid(); -- v4 — Postgres 13+ built-in, no extension
-- v7 needs Postgres 18: SELECT uuidv7();

-- The index-locality payoff, concretely:
-- CREATE TABLE events (id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
--                     ...);

Run the v4 line in the playground. A random v4 primary key scatters inserts across the whole B-tree at scale — v7 (or a ULID) keeps them append-mostly.

Run in the SQL playground →
JSJavaScript
const id = crypto.randomUUID(); // v4, cryptographic

console.log(id); // 36 chars with dashes

Node 14.17+ and secure browser contexts. v7 is not native — the uuid npm package ships uuidv7().

TSTypeScript
// UUIDv7 from scratch: 48-bit ms timestamp + random, version/variant stamped
function uuidv7(): string {
  const buf = crypto.getRandomValues(new Uint8Array(16));
  const ts = BigInt(Date.now());
  for (let i = 0; i < 6; i++) {
    buf[i] = Number((ts >> BigInt((5 - i) * 8)) & 0xffn); // big-endian
  }
  buf[6] = (buf[6] & 0x0f) | 0x70; // version 7
  buf[8] = (buf[8] & 0x3f) | 0x80; // RFC 4122 variant

  const hex = [...buf].map((b) => b.toString(16).padStart(2, '0')).join('');
  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
}

The timestamp prefix is the whole point: v7 keys sort by creation time, so primary-key inserts cluster instead of scattering across the index.

GoGo
// stdlib has no UUID — v4 from crypto/rand
b := make([]byte, 16)
_, _ = rand.Read(b) // crypto/rand, NOT math/rand

b[6] = (b[6] & 0x0f) | 0x40 // version 4
b[8] = (b[8] & 0x3f) | 0x80 // RFC 4122 variant

id := fmt.Sprintf("%x-%x-%x-%x-%x",
	b[0:4], b[4:6], b[6:8], b[8:10], b[10:16])

google/uuid (uuid.New() and uuid.NewV7()) or gofrs/uuid in production — but crypto/rand is the non-negotiable line.

RsRust
use uuid::Uuid; // features = ["v4", "v7"]

fn main() {
    let v4 = Uuid::new_v4();
    let v7 = Uuid::now_v7(); // time-ordered
    println!("{v4} {v7}");
}

The uuid crate gates versions behind Cargo features — v7 needs the "v7" feature flag explicitly.

PHPPHP
// v4 from 16 cryptographic random bytes — dashes and bits are on you
$b = random_bytes(16);
$b[6] = chr((ord($b[6]) & 0x0f) | 0x40);
$b[8] = chr((ord($b[8]) & 0x3f) | 0x80);

$id = vsprintf(
    '%s%s-%s-%s-%s-%s%s%s',
    str_split(bin2hex($b), 4),
);

ramsey/uuid is the package (Uuid::uuid7() included). random_bytes is cryptographic — the old mt_rand snippets are attack surface.

PyPython
import uuid

print(uuid.uuid4())  # v4
print(uuid.uuid7())  # v7 — Python 3.14+

uuid7 landed in the 3.14 stdlib; on older Pythons the uuid6 package backports uuid6/uuid7/uuid8.

C#C#
Guid v4 = Guid.NewGuid();          // v4
Guid v7 = Guid.CreateVersion7();    // v7 — .NET 9+

string dashed = v4.ToString("D");  // dashes
string plain = v4.ToString("N");    // 32 hex chars, no dashes

Guid.NewGuid is v4; CreateVersion7 arrived in .NET 9. Trap: ToByteArray() returns the first 4 bytes reversed — never hand-parse it.

JvJava
import java.util.UUID;

UUID id = UUID.randomUUID(); // v4
System.out.println(id);

JDK ships v4 only. v7 needs java-uuid-generator (or the same 6-line bit-stamp from the Go example on a 6-byte timestamp).

SwSwift
import Foundation

let id = UUID().uuidString // v4 — note: UPPERCASE

uuidString is uppercase, unlike most languages' lowercase — lowercase it when the consumer case-matches. v7 needs a package (swift-uuid) today.

KtKotlin
import java.util.UUID

val id: UUID = UUID.randomUUID() // v4, dashed lowercase by default

Same java.util.UUID; toString() is lowercase-dashed, which is the format most APIs expect.

RbRuby
require 'securerandom'

id = SecureRandom.uuid # v4

SecureRandom wraps the OS CSPRNG — that is the entire reason it is called Secure. v7: the securerandom gem or hand-roll from Time.now.to_f.

ZigZig
const std = @import("std");

pub fn main() !void {
    var b: [16]u8 = undefined;
    std.crypto.random.bytes(&b); // OS CSPRNG

    b[6] = (b[6] & 0x0f) | 0x40; // version 4
    b[8] = (b[8] & 0x3f) | 0x80; // variant

    var hex: [36]u8 = undefined;
    _ = std.fmt.bufPrint(&hex, "{x}-{x}-{x}-{x}-{x}", .{
        b[0..4], b[4..6], b[6..8], b[8..10], b[10..16],
    }) catch unreachable;

    std.debug.print("{s}\n", .{hex});
}

{x} on a byte slice hex-encodes every element — the dashes land exactly at the RFC positions. std.crypto.random is always a CSPRNG.

Keep going

Try the interactive uuid tool →