loghubuuid

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Aug 27, 2026 License: MIT Imports: 6 Imported by: 0

README

go-loghub-uuid

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.

  • 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.

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.

Instalação

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

Uso rápido no Linux

Instalar Go:

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.2.0

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;
GOSUMDB=off go mod download;
#go env -w GOPROXY=direct && go mod download;
#go build .;
go build -o test-uuid test-uuid.go;

Compilar (alternativa):

go env -w GOSUMDB=off;
go get github.com/patrickbrandao/go-loghub-uuid;
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) usa um PRNG estatístico (PCG), não criptográfico. Quem observar alguns identificadores consegue reconstruir o estado interno e prever os seguintes; além disso, 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:

import (
	crand "crypto/rand"
	"encoding/binary"
)

func cryptoBits() uint64 {
	var b [8]byte
	crand.Read(b[:])
	return binary.LittleEndian.Uint64(b[:])
}

var Gen = uuid.NewGeneratorWith(cryptoBits)

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

Constants

This section is empty.

Variables

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).

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 GenerateString

func GenerateString(level Level) string

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

Types

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.

Internamente o gerador padrão mantém um pool de geradores pseudoaleatórios rápidos (PCG) — um por thread em uso — eliminando contenção de lock e permitindo 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 NewGenerator

func NewGenerator() *Generator

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

A entropia em tempo de execução vem de geradores PCG mantidos em um sync.Pool (sem locks compartilhados). Cada PCG é semeado uma única vez, na criação, a partir de crypto/rand (alta qualidade), e depois avança de forma puramente local — barato e contention-free.

ATENÇÃO — o PCG é um gerador pseudoaleatório estatístico, NÃO criptográfico: quem observar alguns UUIDs produzidos por este gerador consegue reconstruir o estado interno e prever os seguintes. Além disso, todo UUIDv7 expõe o instante de criação por construção. Não use estes identificadores como segredo (token de sessão, link privado, chave de recuperação); para esse fim, monte o gerador com entropia criptográfica através de 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 (*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.

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).

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 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.

type UUID

type UUID [16]byte

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

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.

func Generate

func Generate(level Level) UUID

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

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) 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) 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).

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