KPermute generates fast, deterministic, reversible integer permutations over
arbitrary integer domains using bijective hash mixing.
Overview
Each seed defines a unique bijection over [0, size). The result behaves like
a keyed shuffle: repeatable, memory-efficient, and invertible.
Typical uses are obfuscating numeric IDs (such as user or session numbers),
generating reproducible pseudo-random shuffles, collision-free sampling and
load balancing, and masking non-sensitive identifiers. It is not a cryptographic
primitive; if your use case is cryptographic, choose a real cipher.
Installation
implementation("com.eignex:kpermute:1.2.0")
Usage
Obfuscate a numeric ID reproducibly:
val idPerm = longPermutation(seed = 1L)
val longId = 49102490812045Lval encoded = idPerm.encode(longId)
println("encoded: $encoded (always prints 3631103739497407856)")
KPermute builds keyed, reversible permutations over integer domains using
xor-shift-multiply mixers and cycle-walking. It never stores lookup tables, and
every output decodes back to its original value.
A permutation is selected by its size. A positive size means a finite domain
[0, size). A size of -1 or -1L means the full 32- or 64-bit signed
domain. Other negative sizes select the unsigned variants via UIntPermutation
or ULongPermutation.
Range factories like intPermutation(range) and longPermutation(range) wrap
these with a range view, so you can permute directly on intervals such as
-100..199.
Each round multiplies by an odd constant, adds or xors a secret per-round key,
and applies xor-shift steps (x ^= x >>> s) to diffuse bits. Every step is
invertible via modular inverses and xor-shift inversion 13. For
non-power-of-two domains KPermute uses cycle-walking 12: permute in the
next power-of-two space and retry until the output falls in .
References
P. Rogaway and T. Shrimpton,
“Ciphers with Arbitrary Finite Domains,” CT-RSA 2002. PDF
M. Bellare, P. Rogaway, and T. Spies,
“The FFX Mode of Operation for Format-Preserving Encryption,” NIST
submission, 2010.Spec