Skip to content

binadel/idobf

Repository files navigation

idobf — Integer ID Obfuscation for Go

idobf is a composable library for obfuscating integer IDs into human-readable, tamper-evident strings. It is designed for scenarios where you want to expose internal sequential IDs (e.g., database primary keys) to end users without revealing ordering or cardinality.

Features

  • Composable pipeline — mix and match permutations, checksums, and encoders
  • Tamper detection — keyed or non-keyed checksums detect forged IDs
  • Namespaced obfuscation — same ID in different namespaces produces different output
  • Human-readable output — configurable alphabets (Base32, Base58, Base62, etc.)
  • Zero external dependencies — pure Go standard library
  • Fast — optimized power-of-two encode/decode paths

Installation

go get github.com/binadel/idobf

Quick Start

package main

import (
    "fmt"
    "github.com/binadel/idobf"
    "github.com/binadel/idobf/checksums"
    "github.com/binadel/idobf/encoders"
    "github.com/binadel/idobf/permutations"
)

func main() {
    affine, _ := permutations.NewAffine(64, 0x9e3779b97f4a7c15, 0x85ebca6b)
    xor, _ := permutations.NewXor(64, 0xcafebabe)
    rotate, _ := permutations.NewRotate(64, 17)
    cs, _ := checksums.NewSplitMix64(16)
    enc, _ := encoders.NewAlphabetEncoder(
        encoders.AlphabetBase32Crockford,
        64+cs.ChecksumLength(),     // 80 bits
    )

    pipe := idobf.NewPipeline(
        []idobf.Permutation{affine, xor, rotate},
        cs,
        enc,
    )

    obf, _ := pipe.Obfuscate(42, 0)      // namespace = 0
    fmt.Println(string(obf))              // e.g. "6F8TPBV6F8TP"

    id, err := pipe.Restore(obf, 0)       // → 42, nil
    fmt.Println(id, err)
}

API Overview

Core Interfaces

Interface Methods Description
Permutation Forward(uint64) uint64 Bijection over a uint64 domain. Must be invertible.
Reverse(uint64) uint64
Checksum CalculateChecksum(uint64) uint64 Integrity check for an ID value.
ChecksumLength() int Number of bits the checksum occupies.
Encoder Encode([2]uint64) ([]byte, error) 128-bit block ↔ byte representation.
Decode([]byte) ([2]uint64, error)
Obfuscator Obfuscate(uint64, uint64) ([]byte, error) Top-level interface.
Restore([]byte, uint64) (uint64, error)

Pipeline

A Pipeline wires permutations, an optional checksum, and an encoder into an Obfuscator. Use the builder for readable construction:

pipe, err := idobf.NewPipelineBuilder().
    WithPermutations(affine, xor).
    WithChecksum(cs).
    WithEncoder(enc).
    Build()

The pipeline XORs the ID with a namespace, applies permutations, computes a checksum, then encodes the 128-bit block {checksum, permuted_value}.

On restore, it decodes the block, verifies the checksum (returning checksums.ErrChecksum on mismatch), reverses permutations, and XORs the namespace back.

Permutations

Type Constructor Domain Notes
Affine NewAffine(bits, a, b) 2^bits (2–64) f(v) = (a·v + b) mod 2^n. a must be odd.
Xor NewXor(bits, key) 2^bits (2–64) f(v) = v ⊕ key. Self-inverse.
Rotate NewRotate(bits, shift) 2^bits (2–64) Circular bit rotation. shift < bits.
Feistel NewFeistel(bits, keys, fn) 2^bits (2–64, even) Feistel network with configurable round function.

Feistel round functions:

Function Description
DefaultFeistelRound(right, key) Multiply-xor-shift avalanche (MurmurHash3-style)
FastFeistelRound(right, key) Lightweight: rotation + golden ratio multiply
StrongFeistelRound(right, key) Full 32-bit avalanche with xor-shift cascade

Checksums

Type Constructor Keyed Speed
SplitMix64 NewSplitMix64(length) No ~0.3 ns
SipHash NewSipHash(key, length) Yes (128-bit key) ~35 ns

length is the bit size of the checksum (1–64). A longer checksum provides better tamper detection at the cost of reduced data capacity.

Encoders & Alphabets

NewAlphabetEncoder(alphabet, bitSize) creates an encoder. The total bit size should be 64 + checksumLength (or 64 with no checksum).

Predefined alphabets:

Name Base Characters
AlphabetBase2 2 01
AlphabetBase16 16 0123456789abcdef
AlphabetBase32Std 32 abcdefghijklmnopqrstuvwxyz234567
AlphabetBase32Hex 32 0123456789abcdefghijklmnopqrstuv
AlphabetBase32Crockford 32 0123456789abcdefghjkmnpqrstvwxyz
AlphabetBase36 36 0123456789abcdefghijklmnopqrstuvwxyz
AlphabetBase58 58 Bitcoin-style (no 0OIl)
AlphabetBase62 62 0-9a-zA-Z
AlphabetBase64 64 RFC 4648
AlphabetBase64URL 64 URL-safe -_ instead of +/

Namespacing

The namespace value is XORed with the ID before permutation. This means the same ID in different namespaces produces completely different output:

a, _ := pipe.Obfuscate(42, 0)      // "6F8TPB..."
b, _ := pipe.Obfuscate(42, 1001)   // "X2K9MZ..."

Testing

go test ./... -count=1

Benchmarks:

go test ./... -bench=. -benchmem

License

MIT — see LICENSE.

About

The Obfuscator of integer IDs.

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages