loghubuuid

package module
v0.6.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 17 Imported by: 0

README

go-loghub-uuid

ci

Biblioteca Go leve e rápida para gerar UUIDv7 (RFC 9562) com três níveis de precisão temporal, conversões string⇄binário e importação das propriedades de tempo. Gera também todas as demais versões de UUID da RFC 9562 — 1, 2, 3, 4, 5, 6 e 8.

  • Rápida: geração binária em dezenas de nanossegundos, zero alocações, mais de 11 mil UUIDs/ms por núcleo (em VM modesta).
  • Concorrente: um único Generator criado no boot atende centenas de goroutines sem trava global.
  • Sem dependências: apenas a biblioteca padrão do Go.
  • Multinível: do milissegundo padrão até nanossegundos embutidos.
  • Consultável por intervalo: MinAt, MaxAt e RangeAt dão os UUIDs que delimitam uma janela de tempo, para responder a ela com o índice da própria chave primária, sem coluna nem índice de carimbo.
  • Completa: todas as versões da RFC 9562, análise permissiva de texto, serialização em JSON e integração com database/sql, inclusive em coluna binária de 16 bytes.

Níveis

Nível Precisão embutida Compatível UUIDv7
Level1 milissegundos (padrão) Sim
Level2 + microssegundos em rand_a Sim
Level3 + nanossegundos em rand_b Sim

Todos preservam versão 7 e variante RFC.

Todas as versões de UUID

Função Versão Base
GenerateV1 1 tempo gregoriano + nó + sequência
GenerateV2 2 versão 1 com domínio e identificador
GenerateV3 3 resumo MD5 de espaço de nomes + nome
GenerateV4 4 122 bits aleatórios
GenerateV5 5 resumo SHA-1 de espaço de nomes + nome
GenerateV6 6 versão 1 com tempo reordenado, ordenável
GenerateV7 7 tempo Unix em milissegundos (Nível 1)
GenerateV7Level1..3 7 os três níveis pelo nome, sem argumento
Generate(Level1..3) 7 tempo Unix, com os três níveis
GenerateV8 8 122 bits livres, definidos pelo chamador

As versões 1, 2 e 6 compartilham um relógio interno com trava própria. O caminho do UUIDv7 continua sem trava alguma e sem alocações.

GenerateV7 é o UUIDv7 padrão da RFC 9562 pedido pelo nome da versão, como as demais: exatamente Generate(Level1), com precisão de milissegundo, também como método do Generator. Os três níveis também têm nome próprio, sem o argumento de nível: GenerateV7Level1 (o mesmo que GenerateV7), GenerateV7Level2 e GenerateV7Level3 são exatamente Generate com o nível correspondente, e deixam o nível legível no ponto da chamada.

Consulta por intervalo de tempo

É o motivo prático de usar UUIDv7 como chave primária. O índice da chave já está em ordem cronológica, então uma janela de tempo vira varredura de faixa:

lo, hi := uuid.RangeAt(uuid.Level2, inicio, fim)

rows, err := db.Query(
	"SELECT id, corpo FROM eventos WHERE id >= $1 AND id < $2 ORDER BY id",
	lo.String(), hi.String(),
)

RangeAt devolve o intervalo semiaberto [inicio, fim). Para as fronteiras separadas, MinAt e MaxAt. As três respeitam o nível: no Nível 2 o campo rand_a carrega os microssegundos reais do instante, e zerá-lo daria uma fronteira errada.

Para gravar a chave de um instante conhecido, ao reprocessar um histórico, GenerateAt(nível, instante) gera com o tempo que você informa, preservando a ordenação da chave.

A fronteira só vale para UUIDs gravados no mesmo nível. Misturar níveis na mesma coluna faz a consulta devolver linhas a menos, sem erro nenhum. Detalhes em docs/03-guia-completo.md.

Instalação

go get github.com/patrickbrandao/go-loghub-uuid

Uso rápido no Linux

Instalar Go (é necessário Go 1.22 ou superior; confira com go version — se a distribuição empacotar versão inferior, use o instalador oficial):

apt-get update;
apt-get install -y golang-go;

Arquivo go.mod:

module uuid-test

go 1.22

require github.com/patrickbrandao/go-loghub-uuid v0.6.3

O require acima é preenchido automaticamente pelo go get mostrado na seção de compilação; declará-lo à mão é opcional.

Arquivo test-uuid.go:

package main

import (
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	// Gera um UUIDv7 em string (gerador padrão interno, pronto para uso).
	fmt.Println(uuid.GenerateString(uuid.Level1))
	// ex.: 019e99e3-42f0-7882-9719-2305ff84949c
}

Compilar:

go mod download;
go build -o test-uuid test-uuid.go;

Compilar (alternativa):

go get github.com/patrickbrandao/go-loghub-uuid@latest;
go mod tidy;
go build -o test-uuid test-uuid.go;

Compilar (multi plataforma):

# Windows
GOOS=windows GOARCH=amd64 go build -o test-uuid.exe test-uuid.go

# macOS
GOOS=darwin GOARCH=amd64 go build -o test-uuid test-uuid.go

# Linux (outros processadores)
GOOS=linux GOARCH=arm64 go build -o test-uuid test-uuid.go

Rodar:

./test-uuid;
    # 019e9ace-a992-79d2-9460-e33944a68428

Em serviços de alto volume, crie um gerador no boot e reutilize:

var Gen = uuid.NewGenerator()

func newID() string { return Gen.GenerateString(uuid.Level3) }

Aviso de segurança

O gerador padrão (NewGenerator, e as funções de pacote Generate, GenerateString, GenerateV7, GenerateV7Level1 a GenerateV7Level3, GenerateV4 e GenerateV8Random) tira entropia do gerador do runtime do Go, uma instância de ChaCha8 por thread semeada pelo sistema operacional. É uma cifra de fluxo, resistente a predição, e não o PRNG estatístico usado até a v0.3.0. Ainda assim, a própria documentação do Go recomenda crypto/rand para uso sensível a segurança — os apelidos de compatibilidade New, NewString, NewRandom e NewV7 já leem de lá. E, independentemente da fonte, todo UUIDv7 expõe o instante de criação por construção.

Não use estes UUIDs como segredo — token de sessão, link privado, chave de recuperação ou senha de uso único. Para identificadores que precisem ser inadivinháveis, monte o gerador com entropia criptográfica:

var Gen = uuid.NewCryptoGenerator()

NewGeneratorWithReader aceita qualquer io.Reader seguro para uso concorrente, e NewGeneratorWith continua aceitando uma função que devolve 64 bits.

Como identificador de registro, chave primária ou correlação de log — o uso a que a biblioteca se destina — o gerador padrão é adequado.

Mais

Licença

MIT.

Documentation

Overview

Pacote loghubuuid implementa a geração de identificadores UUIDv7 (RFC 9562) com três níveis de precisão temporal.

O UUIDv7 é um identificador de 128 bits ordenável no tempo: os bits mais significativos carregam o instante de criação, de modo que a ordenação lexicográfica das strings coincide com a ordem cronológica.

Esta biblioteca estende o padrão guardando precisão sub-milissegundo dentro dos campos "aleatórios" do UUID, em três níveis:

Level1: apenas milissegundos (48 bits padrão). rand_a e rand_b
        totalmente aleatórios. Compatível 100% com UUIDv7 comum.

Level2: invade rand_a (12 bits) para guardar os microssegundos
        (0-999) do instante. rand_b continua aleatório.

Level3: invade rand_a para os microssegundos e ocupa os 10 bits
        mais altos de rand_b para os nanossegundos (0-999). Os
        52 bits restantes de rand_b continuam aleatórios.

Em todos os níveis a versão (7) e a variante (RFC) são preservadas, portanto o resultado é sempre um UUID válido.

Concorrência: o tipo Generator é seguro para uso simultâneo por centenas de goroutines. Crie um único Generator no boot da aplicação (ou use as funções de pacote, que usam um gerador padrão interno).

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// NameSpaceDNS é o espaço de nomes de domínio.
	NameSpaceDNS = MustParse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")

	// NameSpaceURL é o espaço de nomes de URL.
	NameSpaceURL = MustParse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")

	// NameSpaceOID é o espaço de nomes de OID da ISO.
	NameSpaceOID = MustParse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")

	// NameSpaceX500 é o espaço de nomes de nome distinto X.500.
	NameSpaceX500 = MustParse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")
)

Espaços de nomes conhecidos, definidos na seção 6.6 da RFC 9562. Não altere o valor destas variáveis.

View Source
var (
	// ErrInvalidLength indica comprimento incompatível com todos os
	// formatos aceitos.
	ErrInvalidLength error = &formatError{"loghubuuid: comprimento invalido para string de UUID"}

	// ErrInvalidBrackets indica a forma entre chaves malformada.
	ErrInvalidBrackets error = &formatError{"loghubuuid: chaves invalidas em string de UUID"}
)

Erros mais específicos devolvidos por Parse e ParseBytes. Todos embrulham ErrInvalidFormat, portanto errors.Is(err, ErrInvalidFormat) continua verdadeiro e quem já trata o sentinela antigo não precisa mudar nada.

FromString e StringToBinary não mudaram: continuam devolvendo exatamente ErrInvalidFormat, inclusive para comparação direta com o operador de igualdade.

View Source
var ErrEntropySource = errors.New("loghubuuid: falha ao ler da fonte de entropia")

ErrEntropySource indica que a fonte de entropia informada pelo chamador não conseguiu entregar os bytes pedidos.

View Source
var ErrInvalidFormat = errors.New("loghubuuid: string de UUID em formato inválido")

ErrInvalidFormat indica que a string fornecida não está no formato canônico de UUID (8-4-4-4-12 dígitos hexadecimais).

View Source
var ErrInvalidScanType = errors.New("loghubuuid: tipo nao suportado na leitura de UUID")

ErrInvalidScanType indica que o valor lido do banco não é conversível para UUID.

View Source
var Max = UUID{
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
	0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
}

Max é o UUID com todos os 128 bits em um, definido pela RFC 9562 como limite superior de faixa. Não altere o valor desta variável.

Functions

func BinaryToString

func BinaryToString(u UUID) string

BinaryToString é um apelido explícito para o método String(): converte o binário de 128 bits na string canônica.

func ClockSequence added in v0.3.0

func ClockSequence() int

ClockSequence devolve a sequência de relógio de 14 bits em uso pelos geradores de versão 1, 2 e 6, inicializando-a se ainda não houver uma.

func GenerateAtString added in v0.5.0

func GenerateAtString(level Level, t time.Time) string

GenerateAtString produz, para o instante informado, um UUIDv7 em string usando o gerador padrão do pacote.

func GenerateString

func GenerateString(level Level) string

GenerateString produz um UUID em string usando o gerador padrão do pacote.

Example

A forma mais curta: as funções de pacote usam um gerador padrão interno, já pronto e seguro para concorrência.

package main

import (
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	s1 := uuid.GenerateString(uuid.Level1) // só milissegundos (UUIDv7 padrão)
	s2 := uuid.GenerateString(uuid.Level2) // até microssegundos (rand_a)
	s3 := uuid.GenerateString(uuid.Level3) // até nanossegundos (rand_a + rand_b)
	fmt.Println(len(s1), len(s2), len(s3))
}
Output:
36 36 36

func IsInvalidLengthError added in v0.3.0

func IsInvalidLengthError(err error) bool

IsInvalidLengthError informa se o erro veio de um comprimento incorreto, mesmo que tenha sido embrulhado por outra camada com fmt.Errorf e %w. Equivale a errors.Is(err, ErrInvalidLength), como no pacote github.com/google/uuid.

func NewString added in v0.3.0

func NewString() string

NewString produz um UUID de versão 4 com entropia criptográfica, já em formato canônico de texto.

func NodeID added in v0.3.0

func NodeID() []byte

NodeID devolve uma cópia dos 6 bytes de identificador de nó usados pelos UUIDs de versão 1, 2 e 6.

Por padrão o nó é sorteado uma única vez e marcado como aleatório. Esta biblioteca não lê interfaces de rede, para não arrastar o pacote net para dentro de quem só gera UUIDv7. Para usar um endereço MAC real, leia-o com net.Interfaces e entregue-o a SetNodeID.

func SetClockSequence added in v0.3.0

func SetClockSequence(seq int)

SetClockSequence fixa a sequência de relógio. Só os 14 bits baixos são usados. O valor -1 sorteia uma sequência ainda não usada neste processo.

A biblioteca mantém um piso de relógio por sequência: ao entrar em uma sequência, o próximo instante emitido é estritamente maior que qualquer instante já emitido com ela. Consequências:

  • Um valor explícito pode ser reutilizado à vontade; voltar a uma sequência antiga herda o piso dela e nunca repete um UUIDv1/v6.
  • O adiantamento acumulado do relógio interno só é descartado ao entrar em uma sequência inédita. Para ressincronizar com o relógio do sistema (por exemplo, após detectar que ele foi atrasado), use -1, que garante uma sequência inédita enquanto houver alguma livre.

Isto difere do pacote github.com/google/uuid, que descarta o piso em qualquer troca de sequência e por isso pode repetir um UUIDv1 ao voltar a uma sequência já usada.

func SetNodeID added in v0.3.0

func SetNodeID(id []byte) bool

SetNodeID fixa o identificador de nó a partir dos 6 primeiros bytes de id. Devolve falso, sem alterar nada, se id tiver menos de 6 bytes.

A chamada não mexe no piso do relógio interno: os instantes já emitidos continuam reservados, portanto reaplicar o mesmo nó nunca repete um UUIDv1 ou UUIDv6. Para descartar o adiantamento acumulado do relógio, sorteie uma sequência nova com SetClockSequence(-1).

Os bytes são copiados como estão. Se o valor não for um endereço MAC real, a RFC 9562 seção 6.10 pede o bit 0 do primeiro byte (multicast) ligado, para sinalizar que o nó não identifica uma placa de rede; essa marcação fica a cargo do chamador.

func Validate added in v0.3.0

func Validate(s string) error

Validate informa se a string é um UUID em algum dos formatos aceitos por Parse, devolvendo apenas o erro.

func VariantString added in v0.3.0

func VariantString(v byte) string

VariantString descreve em texto o código de variante devolvido por Variant.

Variant expõe apenas os 2 bits altos do byte 8, portanto o código 3 cobre tanto a variante reservada à Microsoft quanto a reservada para uso futuro; distinguir as duas exigiria um terceiro bit.

func VersionString added in v0.3.0

func VersionString(v byte) string

VersionString descreve em texto o número de versão devolvido por Version.

Types

type BinaryUUID added in v0.5.0

type BinaryUUID UUID

BinaryUUID é um UUID que se entrega ao banco de dados como 16 bytes crus, em ordem de rede, em vez da string canônica de 36 caracteres.

Existe porque a integração padrão é assimétrica de propósito: Scan já aceita 16 bytes crus na leitura, mas Value sempre escreve texto, e mudar Value quebraria em silêncio quem já tem texto gravado — dados novos deixariam de casar com os antigos na mesma coluna.

Use quando a coluna for BINARY(16) ou BLOB, o que é o habitual em MySQL, MariaDB e SQLite, onde não existe tipo nativo de UUID e a forma binária economiza mais da metade do espaço por linha, replicado em todo índice secundário que referencie a chave. No PostgreSQL o tipo uuid é nativo e o driver converte o texto, então não há ganho.

A escolha é por conversão no ponto da consulta, sem estado global e sem efeito sobre quem não usa:

_, err := db.Exec(
    "INSERT INTO eventos (id, corpo) VALUES (?, ?)",
    loghubuuid.BinaryUUID(u), corpo,
)

A ordem dos bytes é a de rede, a mesma de MarshalBinary. Algumas receitas de MySQL sugerem rotacionar os campos do UUIDv1 para melhorar a localidade do índice; não faça isso aqui. O UUIDv7 já nasce ordenado, e o valor rotacionado não seria lido por nenhuma outra ferramenta.

func (BinaryUUID) MarshalBinary added in v0.5.0

func (u BinaryUUID) MarshalBinary() ([]byte, error)

MarshalBinary entrega os 16 bytes crus em ordem de rede.

func (BinaryUUID) MarshalText added in v0.5.0

func (u BinaryUUID) MarshalText() ([]byte, error)

MarshalText devolve a forma canônica, como em UUID, para que o tipo participe de encoding/json e encoding/gob como string.

func (*BinaryUUID) Scan added in v0.5.0

func (u *BinaryUUID) Scan(src any) error

Scan lê um UUID vindo do banco, implementando sql.Scanner. Delega ao Scan de UUID, portanto aceita as mesmas formas: NULL, texto em qualquer formato de Parse, e 16 bytes crus.

Ler por BinaryUUID não exige que a coluna seja binária: o tipo existe para a escrita, e a leitura continua aceitando as duas formas.

func (BinaryUUID) String added in v0.5.0

func (u BinaryUUID) String() string

String devolve a forma canônica, como em UUID. Existe para que um BinaryUUID em mensagem de log ou de erro apareça legível, e não como vetor de bytes.

func (*BinaryUUID) UnmarshalBinary added in v0.5.0

func (u *BinaryUUID) UnmarshalBinary(data []byte) error

UnmarshalBinary lê exatamente 16 bytes crus em ordem de rede.

func (*BinaryUUID) UnmarshalText added in v0.5.0

func (u *BinaryUUID) UnmarshalText(data []byte) error

UnmarshalText lê a forma canônica, aceitando os formatos de Parse.

func (BinaryUUID) Value added in v0.5.0

func (u BinaryUUID) Value() (driver.Value, error)

Value entrega os 16 bytes ao banco, implementando driver.Valuer.

Aloca a fatia devolvida, porque driver.Value é uma interface e o driver pode reter o valor depois do retorno. É uma alocação por parâmetro de consulta, não por identificador gerado.

type Domain added in v0.3.0

type Domain byte

Domain é o domínio de identificação de um UUID de versão 2 (DCE Security), gravado no byte 9.

const (
	// Person identifica um usuário do sistema operacional.
	Person Domain = 0

	// Group identifica um grupo do sistema operacional.
	Group Domain = 1

	// Org identifica uma organização, com significado local.
	Org Domain = 2
)

func (Domain) String added in v0.3.0

func (d Domain) String() string

String descreve o domínio em texto.

type Generator

type Generator struct {
	// contains filtered or unexported fields
}

Generator é o objeto que produz UUIDs. Deve ser criado uma única vez, no boot da aplicação, e pode ser compartilhado por muitas goroutines.

O gerador padrão tira entropia do gerador do runtime do Go (ChaCha8, uma instância por thread, semeada pelo sistema operacional), que não tem trava compartilhada e permite gerar milhões de IDs por segundo.

O valor zero de Generator NÃO é utilizável: use NewGenerator ou NewGeneratorWith. Por segurança, um Generator sem fonte de entropia (valor zero, ou ponteiro nulo) recorre ao gerador padrão do pacote em vez de entrar em pânico.

func NewCryptoGenerator added in v0.3.0

func NewCryptoGenerator() *Generator

NewCryptoGenerator cria um Generator cuja entropia vem inteiramente de crypto/rand, tornando os bits aleatórios imprevisíveis.

É mais lento que NewGenerator, que lê do gerador do runtime. Use este quando o identificador precisar resistir a quem tenta adivinhar o próximo valor. Lembre-se de que, mesmo assim, todo UUIDv7 revela o instante de criação por construção.

Example

NewCryptoGenerator monta um gerador cuja entropia vem inteiramente de crypto/rand, para identificadores que precisem ser inadivinháveis. O gerador padrão é mais rápido, mas a recomendação para segredos continua sendo crypto/rand.

package main

import (
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	gen := uuid.NewCryptoGenerator()

	u := gen.Generate(uuid.Level1)
	fmt.Println(u.Version(), u.Variant())
}
Output:
7 2

func NewGenerator

func NewGenerator() *Generator

NewGenerator cria um Generator rápido e seguro para concorrência.

A entropia em tempo de execução vem das funções de pacote de math/rand/v2, que desde o Go 1.22 leem do gerador do runtime: uma instância de ChaCha8 por thread, semeada pelo sistema operacional na carga do programa. Não há trava compartilhada nem estado a manter, e a leitura é mais barata que a de um pool.

ATENÇÃO — o ChaCha8 é uma cifra de fluxo e resiste a predição, mas a própria documentação do Go recomenda crypto/rand para uso sensível a segurança. Além disso, todo UUIDv7 expõe o instante de criação por construção, independentemente da fonte de entropia. Não use estes identificadores como segredo (token de sessão, link privado, chave de recuperação); para esse fim, use NewCryptoGenerator ou monte o gerador com NewGeneratorWith.

func NewGeneratorWith

func NewGeneratorWith(source func() uint64) *Generator

NewGeneratorWith cria um Generator usando uma fonte de aleatoriedade personalizada. A função "source" deve devolver 64 bits aleatórios e PRECISA ser segura para uso concorrente (ela será chamada por várias goroutines ao mesmo tempo).

Use isto, por exemplo, para forçar entropia criptográfica (crypto/rand) em todas as gerações, abrindo mão de parte da velocidade em troca de imprevisibilidade total.

A fonte é chamada uma única vez por UUID nos níveis 2 e 3 (onde rand_a carrega o tempo) e duas vezes no nível 1.

Entra em pânico se source for nula: é um erro de configuração, que deve aparecer no boot e não na primeira geração.

func NewGeneratorWithReader added in v0.3.0

func NewGeneratorWithReader(reader io.Reader) *Generator

NewGeneratorWithReader cria um Generator que retira entropia de um io.Reader, formato usual das fontes da biblioteca padrão.

O leitor PRECISA ser seguro para uso concorrente, porque será chamado por várias goroutines ao mesmo tempo. crypto/rand.Reader satisfaz esse requisito.

Entra em pânico se reader for nulo, e também se uma leitura falhar durante a geração: uma fonte de entropia quebrada não pode degradar em silêncio para um gerador previsível.

Para a fonte criptográfica padrão, prefira NewCryptoGenerator.

func (*Generator) Generate

func (g *Generator) Generate(level Level) UUID

Generate produz um UUID binário (128 bits) do nível informado, usando o instante atual (time.Now). Níveis desconhecidos são tratados como Level1 (totalmente padrão).

Layout dos 16 bytes (big-endian):

bytes 0..5 : unix_ts_ms .......... 48 bits  (milissegundos desde epoch)
byte  6    : 0x7_ | rand_a[11:8] . versão(4) + 4 bits altos de rand_a
byte  7    : rand_a[7:0] ......... 8 bits baixos de rand_a (total 12 bits)
byte  8    : 10_ | rand_b[61:56] . variante(2) + 6 bits altos de rand_b
bytes 9..15: rand_b[55:0] ........ 56 bits restantes de rand_b (total 62 bits)

Onde, conforme o nível:

rand_a (12 bits) = microssegundos (0-999) nos níveis 2 e 3; aleatório no nível 1.
rand_b[61:52]    = nanossegundos  (0-999) no nível 3; aleatório nos níveis 1 e 2.
demais bits      = aleatórios.

O campo de 48 bits de milissegundos comporta datas até 10889-08-02. Relógios anteriores à época Unix (1970-01-01) degradam para a própria época, em vez de produzirem um timestamp corrompido.

Example

Em serviços de alto volume, crie um único Generator no boot e reutilize-o em todas as goroutines.

package main

import (
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	gen := uuid.NewGenerator()

	u := gen.Generate(uuid.Level3) // u é um uuid.UUID ([16]byte)
	fmt.Println(u.Version(), u.Variant())
}
Output:
7 2

func (*Generator) GenerateAt added in v0.5.0

func (g *Generator) GenerateAt(level Level, t time.Time) UUID

GenerateAt produz um UUIDv7 para um instante informado pelo chamador, em vez do instante atual. É o sentido inverso de Import: ali se lê o tempo de um identificador, aqui se constrói um identificador para um tempo.

Serve para reprocessar um histórico, semear dados de teste e importar registros antigos preservando a ordenação cronológica da chave.

Os campos de tempo são gravados exatamente como em Generate, com a mesma distribuição por nível, e os bits livres recebem entropia deste gerador. Duas chamadas com o mesmo instante devolvem UUIDs DIFERENTES: é um gerador, não um construtor determinístico. Para a forma determinística de um instante, use MinAt e MaxAt.

A unicidade vem inteiramente dos bits livres, que são 74 no Nível 1, 62 no Nível 2 e 52 no Nível 3. Como o instante deixa de vir do relógio, nada impede o chamador de gerar em volume para um único instante, e é só aí que essa margem começa a importar.

Instantes anteriores a 1970-01-01T00:00:00Z degradam para a própria época, como em Generate. Instantes posteriores a 10889-08-02T05:31:50.655999999Z saturam no último instante representável, porque o campo de milissegundos tem 48 bits.

Níveis desconhecidos são tratados como Level1, como em Generate.

func (*Generator) GenerateAtString added in v0.5.0

func (g *Generator) GenerateAtString(level Level, t time.Time) string

GenerateAtString produz, para um instante informado, um UUIDv7 já no formato string canônico. Valem as mesmas observações de GenerateAt.

func (*Generator) GenerateString

func (g *Generator) GenerateString(level Level) string

GenerateString produz um UUID do nível informado já no formato string canônico (8-4-4-4-12, minúsculas).

func (*Generator) GenerateV4 added in v0.3.0

func (g *Generator) GenerateV4() UUID

GenerateV4 produz um UUID de versão 4: 122 bits aleatórios, sem qualquer informação de tempo, com versão e variante fixas.

A entropia vem da fonte deste Generator. No gerador padrão isso significa o ChaCha8 do runtime do Go, que resiste a predição mas cuja documentação recomenda crypto/rand para uso sensível a segurança: para identificadores que precisem ser segredo, monte o gerador com NewCryptoGenerator ou NewGeneratorWithReader.

O caminho é livre de alocações, como o dos demais geradores binários.

func (*Generator) GenerateV7 added in v0.5.0

func (g *Generator) GenerateV7() UUID

GenerateV7 produz um UUID de versão 7 padrão da RFC 9562: carimbo Unix em milissegundos nos 48 bits altos, versão 7, variante RFC e os 74 bits restantes aleatórios. É exatamente Generate(Level1), sob o nome que as demais versões já têm (GenerateV1, GenerateV4, GenerateV6), para que o UUIDv7 comum possa ser pedido pela versão, sem mencionar nível. É o mesmo que GenerateV7Level1.

A precisão embutida é a do milissegundo. Para gravar também os microssegundos ou os nanossegundos, use GenerateV7Level2 ou GenerateV7Level3, ou Generate com Level2 ou Level3. Não há forma em texto, como nas demais funções por versão: use GenerateString(Level1) ou o método String do valor devolvido.

A entropia vem da fonte deste Generator, com o mesmo consumo do Nível 1 (duas palavras de 64 bits), e o caminho é livre de alocações. Vale o mesmo aviso de GenerateV4: no gerador padrão a fonte é o ChaCha8 do runtime do Go, e um identificador que precise ser segredo deve vir de NewCryptoGenerator ou de NewGeneratorWithReader.

O apelido não acrescenta custo ao caminho quente: a implementação continua em Generate, e o compilador embute esta chamada. Ver docs/04-uuidv7-formato-e-niveis.md seção 3.1.

func (*Generator) GenerateV7Level1 added in v0.5.0

func (g *Generator) GenerateV7Level1() UUID

GenerateV7Level1 produz um UUIDv7 de Nível 1: carimbo Unix em milissegundos e os 74 bits restantes aleatórios, o UUIDv7 padrão da RFC 9562. É exatamente Generate(Level1), e portanto o mesmo que GenerateV7; existe para que os três níveis tenham nome, e o nível escolhido fique legível no ponto da chamada em vez de numa constante.

Consome duas palavras de 64 bits da fonte de entropia, como o Nível 1, e não aloca. Não há forma em texto: use GenerateString(Level1) ou o método String do valor devolvido.

func (*Generator) GenerateV7Level2 added in v0.5.0

func (g *Generator) GenerateV7Level2() UUID

GenerateV7Level2 produz um UUIDv7 de Nível 2: carimbo Unix em milissegundos e os microssegundos do instante (0 a 999) em rand_a, com os 62 bits de rand_b aleatórios. É exatamente Generate(Level2), sob um nome que diz o nível.

Consome uma única palavra de 64 bits da fonte de entropia, como o Nível 2, e não aloca. Não há forma em texto: use GenerateString(Level2) ou o método String do valor devolvido.

func (*Generator) GenerateV7Level3 added in v0.5.0

func (g *Generator) GenerateV7Level3() UUID

GenerateV7Level3 produz um UUIDv7 de Nível 3: carimbo Unix em milissegundos, os microssegundos do instante (0 a 999) em rand_a e os nanossegundos (0 a 999) nos 10 bits mais altos de rand_b, com os 52 bits restantes aleatórios. É exatamente Generate(Level3), sob um nome que diz o nível.

Consome uma única palavra de 64 bits da fonte de entropia, como o Nível 3, e não aloca. Não há forma em texto: use GenerateString(Level3) ou o método String do valor devolvido.

func (*Generator) GenerateV8 added in v0.3.0

func (g *Generator) GenerateV8() UUID

GenerateV8 produz um UUID de versão 8 com os 122 bits livres preenchidos pela fonte de entropia deste Generator.

No gerador padrão a fonte é o ChaCha8 do runtime do Go; para segredos, prefira um gerador com entropia criptográfica. Veja o aviso em GenerateV4.

O resultado é indistinguível de um UUIDv4 quanto ao conteúdo; muda apenas o número de versão. Use quando precisar marcar identificadores como pertencentes a um esquema próprio.

type GregorianTime added in v0.3.0

type GregorianTime int64

GregorianTime conta intervalos de 100 nanossegundos desde 15/10/1582. É o formato do campo de tempo dos UUIDs de versão 1, 2 e 6.

func GetTime added in v0.3.0

func GetTime() (GregorianTime, uint16)

GetTime devolve o instante gregoriano corrente e a sequência de relógio em uso, avançando o relógio interno como faria uma geração de UUIDv1.

O segundo retorno traz os 14 bits da sequência com os dois bits de variante da RFC já posicionados (bit 15 ligado, bit 14 desligado), pronto para ser gravado nos bytes 8 e 9 de um UUIDv1 ou UUIDv6 — o mesmo formato devolvido pelo pacote github.com/google/uuid. Para obter apenas a sequência, mascare com 0x3FFF ou use ClockSequence.

func (GregorianTime) Time added in v0.3.0

func (t GregorianTime) Time() time.Time

Time devolve o instante como time.Time em UTC.

func (GregorianTime) UnixTime added in v0.3.0

func (t GregorianTime) UnixTime() (sec, nsec int64)

UnixTime converte o instante gregoriano para a época Unix, devolvendo segundos e a fração em nanossegundos.

O par devolvido é canônico: nsec fica sempre em 0..999_999_999, também para instantes anteriores a 1970, que existem no campo (ele começa em 1582). A divisão é euclidiana, com resto não negativo, e não a truncada da linguagem: com a truncada um tique antes da época sairia como (0, -100) em vez de (-1, 999_999_900). time.Unix normalizaria os dois para o mesmo instante, mas quem consome sec e nsec diretamente não deve receber resto negativo. A resolução é a do campo, 100 ns: os dois dígitos finais de nsec são sempre zero. Ver docs/05-outras-versoes-uuid.md seção 4.1.

Valores fora do domínio do campo (0 .. 2^60-1) são aceitos, mas saturados: se int64(t) < minGregorianTicks, a subtração estouraria int64 e o resultado daria a volta para o futuro distante; nesse caso o cálculo parte de math.MinInt64, devolvendo o menor instante representável em vez de um valor absurdo. O custo é uma comparação que o preditor de desvios elimina no caso comum.

type Level

type Level uint8

Level define quanta precisão temporal é embutida no UUIDv7.

const (
	// Level1 grava apenas milissegundos (48 bits). rand_a e rand_b
	// são totalmente aleatórios. É o UUIDv7 padrão da RFC 9562.
	Level1 Level = 1

	// Level2 grava milissegundos + microssegundos (0-999) em rand_a.
	Level2 Level = 2

	// Level3 grava milissegundos + microssegundos (em rand_a) +
	// nanossegundos (0-999) nos 10 bits mais altos de rand_b.
	Level3 Level = 3
)

type NullBinaryUUID added in v0.5.0

type NullBinaryUUID struct {
	UUID  UUID
	Valid bool // Valid é falso quando a coluna era NULL
}

NullBinaryUUID é o equivalente de NullUUID para coluna binária de 16 bytes que também aceita NULL.

ATENÇÃO — ausência de valor e UUID nulo são coisas diferentes, e confundi-las produz a mesma linha no banco. Com Valid falso, Value devolve NULL; para gravar dezesseis bytes zerados é preciso Valid verdadeiro com UUID igual a Nil. Uma coluna que misture os dois casos não consegue mais distinguir "não havia valor" de "o valor era o UUID nulo".

func (NullBinaryUUID) MarshalBinary added in v0.5.0

func (n NullBinaryUUID) MarshalBinary() ([]byte, error)

MarshalBinary grava os 16 bytes, ou nada quando não há valor.

func (NullBinaryUUID) MarshalJSON added in v0.5.0

func (n NullBinaryUUID) MarshalJSON() ([]byte, error)

MarshalJSON grava a string canônica, ou null quando não há valor.

func (NullBinaryUUID) MarshalText added in v0.5.0

func (n NullBinaryUUID) MarshalText() ([]byte, error)

MarshalText grava a string canônica, ou vazio quando não há valor.

func (*NullBinaryUUID) Scan added in v0.5.0

func (n *NullBinaryUUID) Scan(src any) error

Scan implementa sql.Scanner. NULL, string vazia e fatia de bytes vazia produzem valor ausente (Valid falso), sem erro, como em NullUUID.

func (*NullBinaryUUID) UnmarshalBinary added in v0.5.0

func (n *NullBinaryUUID) UnmarshalBinary(data []byte) error

UnmarshalBinary lê 16 bytes; vazio produz ausência.

func (*NullBinaryUUID) UnmarshalJSON added in v0.5.0

func (n *NullBinaryUUID) UnmarshalJSON(data []byte) error

UnmarshalJSON lê uma string JSON ou null.

func (*NullBinaryUUID) UnmarshalText added in v0.5.0

func (n *NullBinaryUUID) UnmarshalText(data []byte) error

UnmarshalText lê a string canônica; vazio produz ausência.

func (NullBinaryUUID) Value added in v0.5.0

func (n NullBinaryUUID) Value() (driver.Value, error)

Value implementa driver.Valuer: NULL quando não há valor, e os 16 bytes crus quando há.

type NullUUID added in v0.3.0

type NullUUID struct {
	UUID  UUID
	Valid bool // Valid é falso quando a coluna era NULL
}

NullUUID representa um UUID que pode ser nulo no banco de dados, no mesmo espírito de sql.NullString.

Example

NullUUID representa uma coluna que aceita NULL e viaja em JSON como a string canônica ou como null.

package main

import (
	"encoding/json"
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	type Registro struct {
		ID  uuid.UUID     `json:"id"`
		Pai uuid.NullUUID `json:"pai"`
	}

	raiz := Registro{ID: uuid.MustParse("0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff")}
	dados, _ := json.Marshal(raiz)
	fmt.Println(string(dados))

	var lido Registro
	_ = json.Unmarshal([]byte(`{"id":"0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff","pai":"{0192F7C5-1A2B-7C3D-8E4F-AABBCCDDEEFF}"}`), &lido)
	fmt.Println(lido.Pai.Valid, lido.Pai.UUID == lido.ID)
}
Output:
{"id":"0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff","pai":null}
true true

func (NullUUID) MarshalBinary added in v0.3.0

func (n NullUUID) MarshalBinary() ([]byte, error)

MarshalBinary grava os 16 bytes, ou nada quando não há valor.

func (NullUUID) MarshalJSON added in v0.3.0

func (n NullUUID) MarshalJSON() ([]byte, error)

MarshalJSON grava a string canônica, ou null quando não há valor.

func (NullUUID) MarshalText added in v0.3.0

func (n NullUUID) MarshalText() ([]byte, error)

MarshalText grava a string canônica, ou vazio quando não há valor.

func (*NullUUID) Scan added in v0.3.0

func (n *NullUUID) Scan(src any) error

Scan implementa sql.Scanner. NULL, string vazia e fatia de bytes vazia produzem valor ausente (Valid falso), sem erro.

Em caso de erro o identificador não é alterado, mas o booleano cai para falso. É a única exceção à regra de receptor inalterado que vale para os desserializadores (docs/07-parsing-e-conversao.md seção 6.4), e tem motivo próprio: database/sql reaproveita o mesmo destino a cada linha, então um chamador que ignore o erro leria o valor da linha anterior como se fosse o da linha que falhou. Zerar o booleano transforma esse descuido em ausência de valor, e não em dado errado.

func (*NullUUID) UnmarshalBinary added in v0.3.0

func (n *NullUUID) UnmarshalBinary(data []byte) error

UnmarshalBinary lê 16 bytes; entrada vazia produz valor ausente.

Em caso de erro o receptor não é alterado, pelo mesmo motivo de UnmarshalText.

func (*NullUUID) UnmarshalJSON added in v0.3.0

func (n *NullUUID) UnmarshalJSON(data []byte) error

UnmarshalJSON lê uma string JSON em qualquer formato aceito por Parse, ou null.

O caso comum, uma string sem sequências de escape, é lido direto dos bytes, sem alocar. Se a string contiver escapes JSON (por exemplo \u0030 no lugar de 0), a decodificação é delegada ao encoding/json, que os interpreta como faria para o tipo UUID; isso custa uma alocação e só acontece nesse caso raro. Erros de sintaxe JSON viram ErrInvalidFormat.

Em caso de erro o receptor não é alterado.

func (*NullUUID) UnmarshalText added in v0.3.0

func (n *NullUUID) UnmarshalText(data []byte) error

UnmarshalText lê a string canônica; entrada vazia produz valor ausente.

Em caso de erro o receptor não é alterado, como em UnmarshalJSON e no tipo simples: o booleano de um valor que já estava presente continua verdadeiro. Ao contrário de Scan, aqui não há destino reaproveitado entre linhas que justifique a exceção.

func (NullUUID) Value added in v0.3.0

func (n NullUUID) Value() (driver.Value, error)

Value implementa driver.Valuer.

type Time

type Time struct {
	// Seconds é o timestamp Unix em segundos desde 1970-01-01 UTC.
	Seconds int64

	// Milliseconds é a fração do segundo: sempre 0..999.
	Milliseconds int

	// Microseconds é lido de rand_a. Vale 0..999 (fração do
	// milissegundo) quando o UUID é de Level2 ou Level3; em UUIDs de
	// Level1 são 12 bits aleatórios, portanto 0..4095.
	Microseconds int

	// Nanoseconds é lido de rand_b[61:52]. Vale 0..999 (fração do
	// microssegundo) quando o UUID é de Level3; em UUIDs de Level1 ou
	// Level2 são 10 bits aleatórios, portanto 0..1023.
	Nanoseconds int
}

Time reúne as propriedades temporais extraídas de um UUIDv7.

Os campos Microseconds e Nanoseconds só têm significado real se o UUID foi gerado com Level2/Level3 (micro) e Level3 (nano). Para UUIDs de Level1 esses campos contêm bits aleatórios — ainda assim, conforme a especificação, a importação os trata como tempo preciso e devolve o valor lido nos respectivos campos sem julgar a origem.

func Import

func Import(s string) (Time, error)

Import recebe um UUIDv7 em string e devolve suas propriedades de tempo (segundos, milissegundos, microssegundos e nanossegundos). Retorna ErrInvalidFormat se a string não for um UUID canônico válido.

func ImportBinary

func ImportBinary(u UUID) Time

ImportBinary extrai as propriedades de tempo de um UUID binário.

A leitura é "cega" quanto ao nível: ela sempre interpreta rand_a como microssegundos e os 10 bits altos de rand_b como nanossegundos, considerando dados aleatórios como se fossem o tempo preciso.

Example

ImportBinary lê os campos de tempo de um UUIDv7. A leitura é cega quanto ao nível: rand_a é sempre interpretado como microssegundos e o topo de rand_b como nanossegundos, mesmo que o UUID seja de Nível 1 e esses bits sejam aleatórios.

package main

import (
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	// UUIDv7 de Nível 3 montado à mão: 0x0192f7c51a2b ms desde a época,
	// 0x1c3 = 451 microssegundos em rand_a e 0x393 = 915 nanossegundos
	// nos 10 bits altos de rand_b.
	u := uuid.MustParse("0192f7c5-1a2b-71c3-b930-0000aabbccdd")

	t := uuid.ImportBinary(u)
	fmt.Printf("seg=%d ms=%03d us=%03d ns=%03d\n",
		t.Seconds, t.Milliseconds, t.Microseconds, t.Nanoseconds)
}
Output:
seg=1730733742 ms=635 us=451 ns=915

type UUID

type UUID [16]byte

UUID é o valor binário de 128 bits (16 bytes, big-endian / ordem de rede).

var Nil UUID

Nil é o UUID de valor zero, com os 128 bits em zero. Não altere o valor desta variável.

func FromBytes added in v0.3.0

func FromBytes(b []byte) (UUID, error)

FromBytes constrói um UUID a partir de exatamente 16 bytes em ordem de rede. Devolve ErrInvalidLength se o tamanho for outro.

func FromString

func FromString(s string) (UUID, error)

FromString interpreta uma string canônica de UUID e devolve o valor binário de 128 bits. Aceita maiúsculas ou minúsculas. Retorna ErrInvalidFormat se o tamanho, os hifens ou os dígitos forem inválidos.

Em caso de erro o UUID devolvido é sempre o valor zero: nenhum byte parcialmente decodificado vaza para o chamador.

Example

FromString aceita apenas a forma canônica 8-4-4-4-12, em maiúsculas ou minúsculas, e devolve ErrInvalidFormat para qualquer outra coisa.

package main

import (
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	u, err := uuid.FromString("0192F7C5-1A2B-7C3D-8E4F-AABBCCDDEEFF")
	if err != nil {
		fmt.Println("erro:", err)
		return
	}
	fmt.Println(u.String())

	_, err = uuid.FromString("0192f7c51a2b7c3d8e4faabbccddeeff")
	fmt.Println(err == uuid.ErrInvalidFormat) //nolint:errorlint // FromString devolve o sentinela puro; a comparação direta faz parte do contrato
}
Output:
0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff
true

func Generate

func Generate(level Level) UUID

Generate produz um UUID binário usando o gerador padrão do pacote.

func GenerateAt added in v0.5.0

func GenerateAt(level Level, t time.Time) UUID

GenerateAt produz um UUIDv7 para o instante informado usando o gerador padrão do pacote. Ver o método de mesmo nome em Generator.

Example

GenerateAt constrói um UUIDv7 para um instante que você informa, em vez do instante atual. É o sentido inverso de Import, e serve para reprocessar histórico preservando a ordenação cronológica da chave.

Os bits livres são sorteados: com o gerador padrão, duas chamadas com o mesmo instante devolvem valores diferentes. Aqui a entropia é fixa em zero só para o exemplo ter saída verificável.

package main

import (
	"fmt"
	"time"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	quando := time.Date(2019, 3, 14, 10, 0, 0, 123_456_789, time.UTC)
	gen := uuid.NewGeneratorWith(func() uint64 { return 0 })

	u := gen.GenerateAt(uuid.Level3, quando)
	fmt.Println(u)

	// Os campos de tempo voltam exatos no Nível 3, que grava os três.
	t := uuid.ImportBinary(u)
	fmt.Println(t.Seconds, t.Milliseconds, t.Microseconds, t.Nanoseconds)
}
Output:
01697ba4-ed7b-71c8-b150-000000000000
1552557600 123 456 789

func GenerateHash added in v0.3.0

func GenerateHash(h hash.Hash, space UUID, name []byte, version byte) UUID

GenerateHash produz um UUID baseado em nome com a função de resumo informada, gravando o número de versão pedido.

Serve para reproduzir esquemas próprios de derivação. Para as versões da RFC use GenerateV3 ou GenerateV5. Apenas os 4 bits baixos de version são aproveitados, e a variante RFC é sempre aplicada.

func GenerateV1 added in v0.3.0

func GenerateV1() UUID

GenerateV1 produz um UUID de versão 1 (RFC 9562): tempo gregoriano de 60 bits, sequência de relógio de 14 bits e identificador de nó de 48 bits.

O tempo, a sequência e o nó vêm do estado compartilhado do pacote — veja SetNodeID e SetClockSequence. O relógio interno é estritamente crescente, portanto dois UUIDv1 gerados no mesmo processo nunca carregam o mesmo instante.

Layout dos 16 bytes (big-endian):

bytes 0..3 : time_low ................ 32 bits baixos do tempo
bytes 4..5 : time_mid ................ 16 bits intermediários
byte  6    : 0x1_ | time_hi[11:8] .... versão(4) + topo do tempo
byte  7    : time_hi[7:0] ............ resto do topo (12 bits ao todo)
byte  8    : 10_ | clock_seq[13:8] ... variante(2) + topo da sequência
byte  9    : clock_seq[7:0] .......... resto da sequência
bytes 10..15: node ................... 48 bits de identificador de nó

Atenção: o UUIDv1 não é ordenável lexicograficamente, porque os bits menos significativos do tempo vêm primeiro. Para ordenação cronológica use a versão 6 ou a versão 7.

Custo da ordem estrita: quando a geração é mais rápida que o tique de 100 nanossegundos, o relógio interno avança sozinho e o instante embutido fica à frente do relógio do sistema. Em rajadas longas esse adiantamento se acumula, na proporção de um tique por UUID. A RFC 9562 permite o comportamento, mas não conte com o carimbo de tempo de um UUIDv1 ou UUIDv6 como leitura fiel do relógio sob carga sustentada.

func GenerateV2 added in v0.3.0

func GenerateV2(domain Domain, id uint32) UUID

GenerateV2 produz um UUID de versão 2 (DCE Security). Ele parte de um UUIDv1 e substitui dois campos: os 32 bits baixos do tempo passam a carregar o identificador local, e o byte baixo da sequência de relógio passa a carregar o domínio.

Consequência dessa troca: o UUIDv2 perde os 32 bits menos significativos do tempo, portanto o instante embutido tem resolução de poucos minutos e não deve ser lido como carimbo de tempo. Timestamp devolve falso para esta versão.

Atenção: o UUIDv2 identifica um principal — usuário, grupo ou organização — e não um evento. Os bits de tempo que sobram só mudam a cada 2^32 tiques de 100 nanossegundos, cerca de sete minutos, e o avanço de um tique por chamada do relógio interno cai justamente nos bits descartados. Portanto, chamadas repetidas com o mesmo domínio e o mesmo identificador, dentro da mesma janela, devolvem o MESMO UUID; duas chamadas consecutivas são iguais. Sem trocar a sequência de relógio, existem no máximo 64 valores distintos por janela.

A versão 2 é legado do DCE 1.1 e não é recomendada para sistemas novos.

func GenerateV2Group added in v0.3.0

func GenerateV2Group() UUID

GenerateV2Group produz um UUID de versão 2 no domínio Group usando o identificador de grupo do processo.

Em Windows a chamada de sistema devolve -1, e o identificador gravado fica sendo 0xFFFFFFFF.

func GenerateV2Person added in v0.3.0

func GenerateV2Person() UUID

GenerateV2Person produz um UUID de versão 2 no domínio Person usando o identificador de usuário do processo.

Em Windows a chamada de sistema devolve -1, e o identificador gravado fica sendo 0xFFFFFFFF.

func GenerateV3 added in v0.3.0

func GenerateV3(space UUID, name []byte) UUID

GenerateV3 produz um UUID de versão 3: o resumo MD5 do espaço de nomes concatenado com o nome, com versão e variante sobrescritas.

A geração é determinística e não usa entropia: o mesmo par espaço e nome sempre devolve o mesmo UUID, em qualquer máquina e a qualquer momento. Prefira a versão 5, que usa SHA-1.

func GenerateV4 added in v0.3.0

func GenerateV4() UUID

GenerateV4 produz um UUID de versão 4 usando o gerador padrão do pacote.

func GenerateV5 added in v0.3.0

func GenerateV5(space UUID, name []byte) UUID

GenerateV5 produz um UUID de versão 5: os 16 primeiros bytes do resumo SHA-1 do espaço de nomes concatenado com o nome, com versão e variante sobrescritas.

A geração é determinística e não usa entropia: o mesmo par espaço e nome sempre devolve o mesmo UUID, em qualquer máquina e a qualquer momento.

Example

GenerateV5 é determinística: o mesmo par de espaço de nomes e nome sempre devolve o mesmo UUID. O valor abaixo é o vetor de teste da RFC 9562 para o espaço DNS.

package main

import (
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	u := uuid.GenerateV5(uuid.NameSpaceDNS, []byte("www.example.com"))
	fmt.Println(u)
}
Output:
2ed6657d-e927-568b-95e1-2665a8aea6a2

func GenerateV6 added in v0.3.0

func GenerateV6() UUID

GenerateV6 produz um UUID de versão 6 (RFC 9562): os mesmos campos do UUIDv1, porém com o tempo reordenado do bit mais significativo para o menos significativo, de modo que a ordenação lexicográfica coincide com a ordem cronológica.

Layout dos 16 bytes (big-endian):

bytes 0..3 : time_high ............... 32 bits altos do tempo
bytes 4..5 : time_mid ................ 16 bits intermediários
byte  6    : 0x6_ | time_low[11:8] ... versão(4) + topo dos 12 bits baixos
byte  7    : time_low[7:0] ........... resto dos 12 bits baixos
byte  8    : 10_ | clock_seq[13:8] ... variante(2) + topo da sequência
byte  9    : clock_seq[7:0] .......... resto da sequência
bytes 10..15: node ................... 48 bits de identificador de nó

A resolução do campo é de 100 nanossegundos, mais fina que a do UUIDv7 padrão. Ainda assim, prefira o UUIDv7 em bases novas: ele não expõe identificador de nó e é o recomendado pela RFC 9562.

Custo da ordem estrita: quando a geração é mais rápida que o tique de 100 nanossegundos, o relógio interno avança sozinho e o instante embutido fica à frente do relógio do sistema. Em rajadas longas esse adiantamento se acumula, na proporção de um tique por UUID. A RFC 9562 permite o comportamento, mas não conte com o carimbo de tempo de um UUIDv1 ou UUIDv6 como leitura fiel do relógio sob carga sustentada.

func GenerateV7 added in v0.5.0

func GenerateV7() UUID

GenerateV7 produz um UUID de versão 7 padrão (Nível 1) usando o gerador padrão do pacote.

Example

GenerateV7 é o UUIDv7 padrão da RFC 9562 pelo nome da versão, como GenerateV1 e GenerateV4: exatamente Generate(Level1), com precisão de milissegundo. Existe também como método do Generator.

package main

import (
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	u := uuid.GenerateV7()
	fmt.Println(u.Version(), u.Variant())
}
Output:
7 2

func GenerateV7Level1 added in v0.5.0

func GenerateV7Level1() UUID

GenerateV7Level1 produz um UUIDv7 de Nível 1 usando o gerador padrão do pacote. É o mesmo que GenerateV7 e que Generate(Level1).

func GenerateV7Level2 added in v0.5.0

func GenerateV7Level2() UUID

GenerateV7Level2 produz um UUIDv7 de Nível 2 usando o gerador padrão do pacote. É o mesmo que Generate(Level2).

func GenerateV7Level3 added in v0.5.0

func GenerateV7Level3() UUID

GenerateV7Level3 produz um UUIDv7 de Nível 3 usando o gerador padrão do pacote. É o mesmo que Generate(Level3).

Example

GenerateV7Level1, GenerateV7Level2 e GenerateV7Level3 são os três níveis pelo nome, sem o argumento de nível: cada um é exatamente Generate com o nível correspondente, e GenerateV7Level1 é o mesmo que GenerateV7. Existem também como métodos do Generator.

package main

import (
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	u := uuid.GenerateV7Level3() // milissegundos, microssegundos e nanossegundos embutidos
	fmt.Println(u.Version(), u.Variant())
}
Output:
7 2

func GenerateV8 added in v0.3.0

func GenerateV8(data [16]byte) UUID

GenerateV8 produz um UUID de versão 8: formato livre, reservado pela RFC 9562 para esquemas próprios de fornecedor.

Os 16 bytes informados são copiados como estão, e só os 6 bits de versão e variante são sobrescritos. Restam 122 bits sob controle do chamador. Nada aqui é interpretado como tempo, e a ordenação depende inteiramente do conteúdo fornecido.

func GenerateV8Random added in v0.3.0

func GenerateV8Random() UUID

GenerateV8Random produz um UUID de versão 8 aleatório usando o gerador padrão do pacote.

func MaxAt added in v0.5.0

func MaxAt(level Level, t time.Time) UUID

MaxAt devolve o maior UUIDv7 que a biblioteca poderia gerar no instante t, no nível informado — todos os bits livres de entropia em um, com versão 7 e variante RFC preservadas. É o limite superior fechado do instante.

Valem aqui as mesmas observações de MinAt sobre mistura de níveis, resolução da fronteira e saturação nas pontas da faixa representável.

func MinAt added in v0.5.0

func MinAt(level Level, t time.Time) UUID

MinAt devolve o menor UUIDv7 que a biblioteca poderia gerar no instante t, no nível informado — todos os bits livres de entropia em zero, com versão 7 e variante RFC preservadas.

Serve de limite inferior em consulta por intervalo usando o índice da própria chave primária, sem coluna nem índice de carimbo temporal:

SELECT * FROM eventos WHERE id >= ? AND id < ?

ATENÇÃO — a fronteira só vale para UUIDs gravados no MESMO nível. Os bits abaixo do milissegundo significam coisas diferentes em cada nível, então uma fronteira de Nível 3 não delimita corretamente identificadores gravados em Nível 1. Nunca misture níveis na mesma coluna.

A precisão da fronteira é a do nível: no Nível 1 ela delimita o milissegundo inteiro, no Nível 2 o microssegundo e no Nível 3 o nanossegundo. Níveis desconhecidos são tratados como Level1, como em Generate.

Instantes anteriores a 1970-01-01T00:00:00Z devolvem a fronteira da própria época, e instantes posteriores a 10889-08-02T05:31:50.655999999Z devolvem a do último instante representável, porque o campo de milissegundos tem 48 bits. Nas duas pontas a saturação mantém a fronteira monotônica, mas dois instantes distintos fora da faixa passam a devolver o mesmo valor.

Example

MinAt e MaxAt devolvem o menor e o maior UUIDv7 que a biblioteca poderia gerar em um instante, no nível informado. As duas preservam a versão 7 e a variante RFC, e é isso que as torna limites corretos: a fronteira superior do Nível 1 termina em 7fff-bfff, não em ffff-ffff.

No Nível 2 o campo rand_a carrega os microssegundos do instante (456, ou 0x1c8), então ele é igual nas duas fronteiras e só rand_b varia.

package main

import (
	"fmt"
	"time"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	instante := time.Date(2026, 9, 11, 12, 34, 56, 123_456_789, time.UTC)

	fmt.Println(uuid.MinAt(uuid.Level1, instante))
	fmt.Println(uuid.MaxAt(uuid.Level1, instante))
	fmt.Println(uuid.MinAt(uuid.Level2, instante))
	fmt.Println(uuid.MaxAt(uuid.Level2, instante))
}
Output:
01a09076-bdfb-7000-8000-000000000000
01a09076-bdfb-7fff-bfff-ffffffffffff
01a09076-bdfb-71c8-8000-000000000000
01a09076-bdfb-71c8-bfff-ffffffffffff

func Must added in v0.3.0

func Must(u UUID, err error) UUID

Must devolve u, ou entra em pânico se err não for nula. Serve para encadear com funções que devolvem par de valores.

func MustParse added in v0.3.0

func MustParse(s string) UUID

MustParse interpreta um UUID em qualquer formato aceito por Parse e entra em pânico se a string for inválida.

Destina-se a constantes do próprio código, como espaços de nomes; nunca use com entrada vinda de fora do programa.

func New added in v0.3.0

func New() UUID

New produz um UUID de versão 4 com entropia criptográfica. Entra em pânico se a leitura de crypto/rand falhar, como uuid.New de origem.

func NewDCEGroup added in v0.3.0

func NewDCEGroup() (UUID, error)

NewDCEGroup produz um UUID de versão 2 no domínio Group. O erro é sempre nulo.

func NewDCEPerson added in v0.3.0

func NewDCEPerson() (UUID, error)

NewDCEPerson produz um UUID de versão 2 no domínio Person. O erro é sempre nulo.

func NewDCESecurity added in v0.3.0

func NewDCESecurity(domain Domain, id uint32) (UUID, error)

NewDCESecurity produz um UUID de versão 2. O erro é sempre nulo.

func NewHash added in v0.3.0

func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID

NewHash produz um UUID baseado em nome com a função de resumo informada.

func NewMD5 added in v0.3.0

func NewMD5(space UUID, data []byte) UUID

NewMD5 produz um UUID de versão 3.

func NewRandom added in v0.3.0

func NewRandom() (u UUID, err error)

NewRandom produz um UUID de versão 4 com entropia criptográfica. Devolve ErrEntropySource se a leitura falhar.

func NewRandomFromReader added in v0.3.0

func NewRandomFromReader(r io.Reader) (UUID, error)

NewRandomFromReader produz um UUID de versão 4 com 16 bytes lidos do leitor informado.

Monta um Generator descartável a cada chamada. Para uso repetido, prefira guardar o resultado de NewGeneratorWithReader.

func NewSHA1 added in v0.3.0

func NewSHA1(space UUID, data []byte) UUID

NewSHA1 produz um UUID de versão 5.

func NewUUID added in v0.3.0

func NewUUID() (UUID, error)

NewUUID produz um UUID de versão 1. O erro é sempre nulo.

func NewV6 added in v0.3.0

func NewV6() (UUID, error)

NewV6 produz um UUID de versão 6. O erro é sempre nulo.

func NewV7 added in v0.3.0

func NewV7() (u UUID, err error)

NewV7 produz um UUID de versão 7 padrão (Level1) com entropia criptográfica, como o pacote de origem. Devolve ErrEntropySource se a leitura falhar. Para velocidade máxima use GenerateV7 ou Generate(Level1), que leem do gerador do runtime.

Para gravar precisão sub-milissegundo, use GenerateV7Level2 ou GenerateV7Level3, ou Generate com Level2 ou Level3.

func NewV7FromReader added in v0.3.0

func NewV7FromReader(r io.Reader) (UUID, error)

NewV7FromReader produz um UUID de versão 7 com 16 bytes lidos do leitor informado.

Monta um Generator descartável a cada chamada. Para uso repetido, prefira guardar o resultado de NewGeneratorWithReader.

func Parse added in v0.3.0

func Parse(s string) (UUID, error)

Parse interpreta um UUID em qualquer um dos quatro formatos usuais:

xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx        canônico, 36 caracteres
urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx   URN, 45 caracteres
{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}      entre chaves, 38 caracteres
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx            hexadecimal cru, 32 caracteres

Maiúsculas e minúsculas são aceitas, inclusive no prefixo URN. Em caso de erro o UUID devolvido é sempre Nil.

Use FromString quando quiser aceitar somente o formato canônico.

Example

Parse aceita as quatro formas usuais de escrever um UUID; todas produzem o mesmo valor.

package main

import (
	"fmt"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	inputs := []string{
		"0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff",
		"{0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff}",
		"urn:uuid:0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff",
		"0192f7c51a2b7c3d8e4faabbccddeeff",
	}
	for _, in := range inputs {
		u, err := uuid.Parse(in)
		if err != nil {
			fmt.Println("erro:", err)
			continue
		}
		fmt.Println(u)
	}
}
Output:
0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff
0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff
0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff
0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff

func ParseBytes added in v0.3.0

func ParseBytes(b []byte) (UUID, error)

ParseBytes faz o mesmo que Parse a partir de uma sequência de bytes, sem converter para string e sem alocar.

func RangeAt added in v0.5.0

func RangeAt(level Level, from, to time.Time) (lo, hi UUID)

RangeAt devolve as duas fronteiras de um intervalo SEMIABERTO [from, to) no nível informado, prontas para a comparação usual:

lo, hi := loghubuuid.RangeAt(loghubuuid.Level2, inicio, fim)
rows, err := db.Query(
    "SELECT * FROM eventos WHERE id >= $1 AND id < $2",
    lo.String(), hi.String(),
)

O limite inferior é MinAt(level, from) e o superior é MinAt(level, to): identificadores gerados no instante to ficam de fora, os gerados em from ficam dentro. Para um intervalo fechado, use MinAt e MaxAt diretamente.

A exclusão vale na resolução do nível. No Nível 1 o intervalo termina no início do milissegundo de to, e portanto exclui esse milissegundo inteiro; no Nível 2 termina no microssegundo de to e no Nível 3 no nanossegundo.

RangeAt não ordena os argumentos: passar to anterior a from devolve um intervalo vazio, que é o que a comparação vai refletir.

Valem aqui as mesmas observações de MinAt sobre mistura de níveis e saturação nas pontas da faixa representável.

Example

RangeAt devolve as duas fronteiras de um intervalo semiaberto, prontas para consultar por faixa usando o índice da própria chave primária:

SELECT * FROM eventos WHERE id >= $1 AND id < $2 ORDER BY id

A fronteira só vale para identificadores gravados no mesmo nível: os bits abaixo do milissegundo significam coisas diferentes em cada um.

package main

import (
	"fmt"
	"time"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	inicio := time.Date(2026, 9, 11, 12, 34, 56, 123_456_789, time.UTC)
	fim := inicio.Add(time.Millisecond)

	lo, hi := uuid.RangeAt(uuid.Level2, inicio, fim)
	fmt.Println(lo)
	fmt.Println(hi)
}
Output:
01a09076-bdfb-71c8-8000-000000000000
01a09076-bdfc-71c8-8000-000000000000

func StringToBinary

func StringToBinary(s string) (UUID, error)

StringToBinary é um apelido explícito para FromString: converte a string canônica no binário de 128 bits.

func (UUID) AppendBinary added in v0.5.0

func (u UUID) AppendBinary(dst []byte) ([]byte, error)

AppendBinary escreve os 16 bytes em ordem de rede no fim de dst e devolve o slice estendido, com a assinatura da interface encoding.BinaryAppender, introduzida no Go 1.24 junto da encoding.TextAppender que AppendText satisfaz. O erro devolvido é sempre nulo.

Não aloca quando dst tem capacidade sobrando; passar nil é válido e faz a função alocar os 16 bytes.

Ao contrário do lado do texto, aqui não existe uma segunda forma sem erro. AppendTo existe porque a formatação canônica é um cálculo; os bytes não são: append(dst, u[:]...) é exatamente o corpo deste método, e o chamador que não quer o erro sempre nulo escreve a linha direto. O método existe para satisfazer a interface.

A interface não é referenciada em lugar nenhum do pacote, então o método compila também nas versões anteriores do Go, onde simplesmente não satisfaz interface alguma. Isso mantém o go.mod em 1.22, como em AppendText.

O conteúdo é idêntico ao de MarshalBinary, portanto acrescentar este método NÃO muda formato de dados gravado — ao contrário do que aconteceu quando MarshalText passou a existir.

func (UUID) AppendText added in v0.4.0

func (u UUID) AppendText(dst []byte) ([]byte, error)

AppendText é AppendTo com a assinatura da interface encoding.TextAppender, introduzida no Go 1.24. O erro devolvido é sempre nulo.

A interface não é referenciada em lugar nenhum do pacote, então o método compila também nas versões anteriores, onde simplesmente não satisfaz interface alguma. Isso mantém o go.mod em 1.22.

func (UUID) AppendTo added in v0.4.0

func (u UUID) AppendTo(dst []byte) []byte

AppendTo escreve a forma canônica de 36 bytes no fim de dst e devolve o slice estendido, como fazem as funções Append da biblioteca padrão.

É o caminho mais barato para serializar muitos identificadores: não aloca nada quando dst tem capacidade sobrando, enquanto String paga uma alocação por chamada. Reaproveite o mesmo buffer entre chamadas:

buf = u.AppendTo(buf[:0])

Passar nil é válido e faz a função alocar os 36 bytes.

func (UUID) Bytes added in v0.4.0

func (u UUID) Bytes() []byte

Bytes devolve uma cópia dos 16 bytes em ordem de rede. Alterar o resultado não afeta o UUID de origem.

Equivale a MarshalBinary sem o erro sempre nulo. Dentro do pacote do chamador, u[:] é mais barato e não copia, mas devolve um slice apoiado no próprio valor: use Bytes quando o destino guardar a referência.

Serve também para contornar uma armadilha de formatação: como UUID satisfaz fmt.Stringer, %x sobre um UUID formata a string canônica, não os bytes. fmt.Printf("%x", u.Bytes()) imprime os 32 dígitos esperados.

func (UUID) ClockSequence added in v0.3.0

func (u UUID) ClockSequence() (int, bool)

ClockSequence extrai a sequência de relógio dos UUIDs de versão 1, 2 e 6. Nas versões 1 e 6 ela tem 14 bits. Na versão 2 o byte baixo da sequência é ocupado pelo domínio, portanto restam apenas os 6 bits altos (0 a 63). O segundo retorno é falso para as demais versões.

func (UUID) Compare added in v0.3.0

func (u UUID) Compare(other UUID) int

Compare ordena dois UUIDs pela sequência de bytes, devolvendo -1, 0 ou 1. Para UUIDs de versão 6 ou 7 a ordem coincide com a ordem cronológica.

Para simples igualdade não é preciso chamar nada: UUID é um vetor de bytes e aceita o operador de igualdade diretamente.

func (UUID) Domain added in v0.3.0

func (u UUID) Domain() (Domain, bool)

Domain extrai o domínio de um UUID de versão 2. O segundo retorno é falso para as demais versões.

func (UUID) GregorianTime added in v0.3.0

func (u UUID) GregorianTime() (GregorianTime, bool)

GregorianTime extrai o campo de tempo dos UUIDs de versão 1 e 6, em intervalos de 100 nanossegundos desde 15/10/1582.

O segundo retorno é falso para as demais versões, inclusive a 2: o UUIDv2 sacrifica os 32 bits baixos do tempo para guardar o identificador local, e o que sobra não é um carimbo utilizável.

func (UUID) ID added in v0.3.0

func (u UUID) ID() (uint32, bool)

ID extrai o identificador local de um UUID de versão 2. O segundo retorno é falso para as demais versões.

func (UUID) IsMax added in v0.3.0

func (u UUID) IsMax() bool

IsMax informa se o UUID tem todos os bits em um.

func (UUID) IsValid added in v0.4.0

func (u UUID) IsValid() bool

IsValid informa se o UUID tem a forma prevista pela RFC 9562: variante RFC (0b10) e número de versão entre 1 e 8.

Nil e Max são aceitos apesar de não carregarem versão nem variante: a RFC 9562 seção 5.9 e 5.10 os define como valores especiais válidos. Para distinguir esses dois casos, use IsZero e IsMax.

A verificação não é específica do UUIDv7: um UUIDv4 gerado em outro lugar também é válido. Para exigir a versão 7, compare Version com 7.

func (UUID) IsZero added in v0.3.0

func (u UUID) IsZero() bool

IsZero informa se o UUID é o valor nulo.

func (UUID) MarshalBinary added in v0.3.0

func (u UUID) MarshalBinary() ([]byte, error)

MarshalBinary devolve os 16 bytes do UUID em ordem de rede. Implementa encoding.BinaryMarshaler.

func (UUID) MarshalText added in v0.3.0

func (u UUID) MarshalText() ([]byte, error)

MarshalText devolve a representação canônica em texto, com 36 bytes. Implementa encoding.TextMarshaler, o que faz encoding/json gravar o UUID como string.

func (UUID) NodeID added in v0.3.0

func (u UUID) NodeID() []byte

NodeID extrai uma cópia dos 6 bytes de identificador de nó dos UUIDs de versão 1, 2 e 6. Devolve nulo para as demais versões.

func (*UUID) Scan added in v0.3.0

func (u *UUID) Scan(src any) error

Scan lê um UUID vindo do banco de dados, implementando sql.Scanner.

Aceita:

nil      — grava o UUID nulo
string   — interpretado por Parse, em qualquer formato aceito;
           a string vazia grava o UUID nulo, sem erro
[]byte   — 16 bytes viram o valor binário; vazio grava o UUID nulo;
           outro tamanho é texto

Texto vazio equivale a ausência de valor, como no pacote github.com/google/uuid: colunas de texto cujo valor padrão é a string vazia não devem falhar na leitura.

Em caso de erro o receptor não é alterado.

func (UUID) String

func (u UUID) String() string

String converte o UUID binário (16 bytes) na representação canônica em texto: 32 dígitos hexadecimais minúsculos agrupados como 8-4-4-4-12 e separados por hifens. Exemplo:

0192f7c5-1a2b-7c3d-8e4f-aabbccddeeff

A implementação escreve diretamente em um buffer de 36 bytes, sem alocações intermediárias, para ser barata em caminhos quentes.

Atenção: por UUID satisfazer fmt.Stringer, os verbos %x e %X do pacote fmt formatam esta string — devolvendo 72 caracteres com o hexadecimal do texto — e não os 16 bytes. Para imprimir os bytes, converta antes: fmt.Printf("%x", u[:]).

func (UUID) Timestamp added in v0.3.0

func (u UUID) Timestamp() (time.Time, bool)

Timestamp devolve o instante de criação embutido no UUID, em UTC.

Funciona para as versões 1 e 6, com resolução de 100 nanossegundos, e para a versão 7, com resolução de milissegundo. Devolve falso para as versões que não carregam tempo — 2, 3, 4, 5 e 8.

Para recuperar também os microssegundos e nanossegundos gravados pelos níveis 2 e 3 desta biblioteca, use TimestampWithLevel.

func (UUID) TimestampWithLevel added in v0.3.0

func (u UUID) TimestampWithLevel(level Level) (time.Time, bool)

TimestampWithLevel devolve o instante de criação de um UUIDv7 em UTC, reconstruindo a precisão sub-milissegundo gravada pelo nível informado.

O nível não pode ser deduzido do UUID, por isso precisa ser informado pelo chamador. Se algum campo lido estiver fora da faixa 0 a 999 — o que denuncia bits aleatórios, e não tempo — todos os campos sub-milissegundo são descartados e devolve-se apenas o milissegundo. No nível 3 os dois campos vêm da mesma geração: um rand_a fora da faixa prova que o topo de rand_b também é ruído, mesmo que caiba em 0 a 999 por acaso.

Devolve falso se o UUID não for de versão 7.

Example

TimestampWithLevel reconstrói o instante com a precisão do nível informado. O nível não pode ser deduzido do UUID, por isso o chamador precisa dizê-lo.

package main

import (
	"fmt"
	"time"

	uuid "github.com/patrickbrandao/go-loghub-uuid"
)

func main() {
	// O mesmo UUID de Nível 3 usado em ExampleImportBinary.
	u := uuid.MustParse("0192f7c5-1a2b-71c3-b930-0000aabbccdd")

	ms, _ := u.Timestamp() // só o milissegundo, como qualquer UUIDv7
	l3, _ := u.TimestampWithLevel(uuid.Level3)

	fmt.Println(ms.Format(time.RFC3339Nano))
	fmt.Println(l3.Format(time.RFC3339Nano))
}
Output:
2024-11-04T15:22:22.635Z
2024-11-04T15:22:22.635451915Z

func (UUID) URN added in v0.3.0

func (u UUID) URN() string

URN devolve a representação como URN da RFC 8141, ou seja, a string canônica prefixada por "urn:uuid:".

func (*UUID) UnmarshalBinary added in v0.3.0

func (u *UUID) UnmarshalBinary(data []byte) error

UnmarshalBinary lê exatamente 16 bytes em ordem de rede. Implementa encoding.BinaryUnmarshaler.

Em caso de erro o receptor não é alterado.

func (*UUID) UnmarshalText added in v0.3.0

func (u *UUID) UnmarshalText(data []byte) error

UnmarshalText lê a representação em texto, aceitando os mesmos quatro formatos de Parse. Implementa encoding.TextUnmarshaler.

Em caso de erro o receptor não é alterado.

func (UUID) Value added in v0.3.0

func (u UUID) Value() (driver.Value, error)

Value entrega o UUID ao banco de dados como a string canônica, implementando driver.Valuer.

O texto é o formato gravado desde a primeira versão e não vai mudar: uma coluna que já recebeu texto e passasse a receber binário ficaria com dois formatos misturados, e nenhuma consulta acharia as linhas antigas. Para gravar em coluna binária de 16 bytes, converta para BinaryUUID no ponto da consulta.

func (UUID) Variant

func (u UUID) Variant() byte

Variant devolve os 2 bits altos do byte 8 (deve ser 0b10 = 2 = variante RFC).

func (UUID) Version

func (u UUID) Version() byte

Version devolve o nibble de versão (deve ser 7 para UUIDs gerados aqui).

type UUIDs added in v0.3.0

type UUIDs []UUID

UUIDs é uma lista de UUIDs, com conveniências para logs e consultas.

func (UUIDs) Strings added in v0.3.0

func (list UUIDs) Strings() []string

Strings converte a lista para as representações canônicas em texto.

Directories

Path Synopsis
Pacote tests contém a suíte de testes funcionais, os benchmarks e utilitários de validação da biblioteca go-loghub-uuid.
Pacote tests contém a suíte de testes funcionais, os benchmarks e utilitários de validação da biblioteca go-loghub-uuid.
benchmark-bulk command
Comando benchmark-bulk gera 1.000.000 de UUIDv7 de cada nível e imprime um relatório de tempo e throughput.
Comando benchmark-bulk gera 1.000.000 de UUIDv7 de cada nível e imprime um relatório de tempo e throughput.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL