dpuid

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 19, 2026 License: MIT Imports: 8 Imported by: 0

README

Delta-Pack UUID (DPUID)

Go Reference Go Report Card Tests Go Version gofmt License

Delta-Pack UUID packs a same-sign integer sequence into a DPUID byte payload, UUID, or base64 string using the format described in SPEC.md. It is optimized for sequences where neighboring absolute values have small deltas.

Russian README: README.ru.md.

Features

  • RFC 9562 UUIDv8 mode by default, using github.com/google/uuid.UUID.
  • Raw 128-bit mode for closed systems that do not need RFC UUID markers.
  • Variable-length and fixed-size byte payloads with base64 adapters.
  • Generic input and output for int, int8..int64, uint, and uint8..uint64.
  • Three SPEC variants: general deltas, sequential unit-step values, and identical values.
  • No runtime dependencies except github.com/google/uuid.
  • Go 1.20 module target.

Install

go get github.com/Vitalick/dpuid

Usage

package main

import (
	"fmt"
	"log"

	"github.com/Vitalick/dpuid"
)

func main() {
	id, err := dpuid.Pack([]int64{1_000_040, 1_000_010, 1_000_030, 1_000_000})
	if err != nil {
		log.Fatal(err)
	}

	values, err := dpuid.Unpack(id)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(id.String())
	fmt.Println(values) // [1000000 1000010 1000030 1000040]
}

Pack and Unpack use UUIDv8 mode. Use PackMode and UnpackMode for raw mode:

id, err := dpuid.PackMode(values, dpuid.ModeRaw)
values, err = dpuid.UnpackMode(id, dpuid.ModeRaw)

Use the generic API for other integer types, including unsigned values:

id, err := dpuid.PackValues([]uint64{1<<63 + 6, 1<<63 + 2, 1<<63 + 4})
if err != nil {
	log.Fatal(err)
}

values, err := dpuid.UnpackValues[uint64](id)
if err != nil {
	log.Fatal(err)
}

fmt.Println(values) // [9223372036854775810 9223372036854775812 9223372036854775814]

Use the byte codec directly when no text or UUID transport is needed. Zero bits selects the minimum byte-aligned payload; a positive value sets an exact bit limit:

data, err := dpuid.PackBytes([]int16{20, 10, 13}, 0)
values, err := dpuid.UnpackBytes[int16](data, 0)

fixed, err := dpuid.PackBytes([]int16{20, 10, 13}, 64)
values, err = dpuid.UnpackBytes[int16](fixed, 64)

Base64 uses the same byte codec:

encoded, err := dpuid.PackBase64([]int8{10, 13, 11, 12}) // "Olg="
values8, err := dpuid.UnpackBase64[int8](encoded)

fixedEncoded, err := dpuid.PackBase64Bits([]uint32{100, 104, 108}, 96)
values32, err := dpuid.UnpackBase64Bits[uint32](fixedEncoded, 96)

Important Behavior

Input values must be sign-homogeneous: all values are non-negative or all values are non-positive. Zero can be encoded with either group. Mixed positive and negative values are rejected.

Unsigned values are always treated as non-negative. The generic type passed to an unpack function must match the type used for packing because the element width determines the encoded field widths.

The input order is not preserved. Decoded values are sorted by absolute value, as required by the SPEC.

Raw mode uses all 128 bits for DPUID data and does not produce an RFC-compliant UUID. UUIDv8 mode is the recommended default for UUID-aware systems.

Validation

The package exposes sentinel errors such as ErrEmptyInput, ErrMixedSigns, ErrDeltaOverflow, ErrCountOverflow, ErrTotalOverflow, ErrInvalidMode, ErrInvalidUUIDv8, ErrInvalidBase64, ErrInvalidBitLimit, and ErrPayloadOverflow. Returned errors can be checked with errors.Is.

Benchmarks

Snapshot from go test -bench=. ./... on linux/amd64, AMD Ryzen 9 3900X:

BenchmarkPackVariant1-24                   1703496     709.6 ns/op
BenchmarkUnpackVariant1-24                 1517302     807.5 ns/op
BenchmarkPackSequentialVariant2-24         1759216     730.2 ns/op
BenchmarkUnpackSequentialVariant2-24        917816      1140 ns/op
BenchmarkPackIdenticalVariant3-24          1751436     673.4 ns/op
BenchmarkUnpackIdenticalVariant3-24         963639      1144 ns/op

Development

go test ./...
go test -bench=. ./...
gofmt -w .

Documentation

Overview

Package dpuid packs same-sign integer sequences into Delta-Pack UUID byte, base64, or UUID values and unpacks them into absolute-value sorted slices.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrEmptyInput      = errors.New("dpuid: empty input")
	ErrMixedSigns      = errors.New("dpuid: mixed signs")
	ErrDeltaOverflow   = errors.New("dpuid: max delta too large")
	ErrCountOverflow   = errors.New("dpuid: too many numbers")
	ErrTotalOverflow   = errors.New("dpuid: encoded payload exceeds output size")
	ErrInvalidMode     = errors.New("dpuid: invalid mode")
	ErrInvalidUUIDv8   = errors.New("dpuid: invalid UUIDv8 markers")
	ErrInvalidBase64   = errors.New("dpuid: invalid base64")
	ErrInvalidBitLimit = errors.New("dpuid: invalid bit limit")
	ErrPayloadOverflow = errors.New("dpuid: payload exceeds input size")
	ErrValueOverflow   = errors.New("dpuid: value overflows target integer type")
)

Functions

func Pack

func Pack(values []int64) (uuid.UUID, error)

Pack encodes values in UUIDv8 mode.

func PackBase64 added in v1.1.0

func PackBase64[T Integer](values []T) (string, error)

PackBase64 encodes values into a variable-length RFC 4648 base64 string.

func PackBase64Bits added in v1.1.0

func PackBase64Bits[T Integer](values []T, outputBits int) (string, error)

PackBase64Bits encodes values into base64 using the requested payload size. A zero outputBits value selects the minimum byte-aligned payload size.

func PackBytes added in v1.1.0

func PackBytes[T Integer](values []T, outputBits int) ([]byte, error)

PackBytes encodes values into an MSB-first DPUID payload. A zero outputBits value selects a variable-length byte-aligned payload; a positive value sets the exact usable bit limit.

func PackMode

func PackMode(values []int64, mode Mode) (uuid.UUID, error)

PackMode encodes values according to SPEC.md.

The input order is not preserved. Decoding returns values sorted ascending by absolute value. Values must be sign-homogeneous: all non-negative or all non-positive.

func PackValues

func PackValues[T Integer](values []T) (uuid.UUID, error)

PackValues encodes signed or unsigned integer values in UUIDv8 mode.

func PackValuesMode

func PackValuesMode[T Integer](values []T, mode Mode) (uuid.UUID, error)

PackValuesMode encodes signed or unsigned integer values according to SPEC.md.

func Unpack

func Unpack(id uuid.UUID) ([]int64, error)

Unpack decodes a UUIDv8 DPUID value.

func UnpackBase64 added in v1.1.0

func UnpackBase64[T Integer](value string) ([]T, error)

UnpackBase64 decodes a variable-length RFC 4648 base64 DPUID payload.

func UnpackBase64Bits added in v1.1.0

func UnpackBase64Bits[T Integer](value string, inputBits int) ([]T, error)

UnpackBase64Bits decodes a base64 DPUID payload with the requested bit size. A zero inputBits value selects the variable-length byte-aligned layout.

func UnpackBytes added in v1.1.0

func UnpackBytes[T Integer](data []byte, inputBits int) ([]T, error)

UnpackBytes decodes an MSB-first DPUID payload. A zero inputBits value selects the variable-length byte-aligned layout; a positive value is the exact usable bit limit and must match the supplied buffer size.

func UnpackMode

func UnpackMode(id uuid.UUID, mode Mode) ([]int64, error)

UnpackMode decodes a DPUID value encoded in the selected mode.

func UnpackValues

func UnpackValues[T Integer](id uuid.UUID) ([]T, error)

UnpackValues decodes a UUIDv8 DPUID value into the requested integer type.

func UnpackValuesMode

func UnpackValuesMode[T Integer](id uuid.UUID, mode Mode) ([]T, error)

UnpackValuesMode decodes a DPUID value encoded in the selected mode into the requested integer type.

Types

type Integer

type Integer interface {
	~int | ~int8 | ~int16 | ~int32 | ~int64 |
		~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
}

Integer is any built-in signed or unsigned integer type up to 64 bits.

type Mode

type Mode int

Mode selects how DPUID data is embedded into the returned UUID value.

const (
	// ModeUUIDv8 stores 122 DPUID bits around RFC 9562 UUID version and variant
	// marker bits. This is the recommended default.
	ModeUUIDv8 Mode = iota

	// ModeRaw uses all 128 UUID bits for DPUID data and does not produce an
	// RFC-compliant UUID.
	ModeRaw
)

Jump to

Keyboard shortcuts

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