block_id
block_id
is a Rust library for generating opaque, unique, and short string values from (unsigned) integers.
tl;dr:
```rust use block_id::{Alphabet, BlockId};
fn main() { // Random seed. let seed = 9876;
// Code length.
let length = 5;
let generator = BlockId::new(Alphabet::alphanumeric(), seed, length);
// Number to string.
assert_eq!("wjweA", &generator.encode_string(0));
assert_eq!("ZxJrE", &generator.encode_string(1));
assert_eq!("3e0IT", &generator.encode_string(2));
// String to number.
assert_eq!(2, generator.decode_string("3e0IT"));
} ```
Random-looking alphanumeric strings are often used in place of sequential numeric IDs for user-facing purposes. This has several advantages:
block_id
is the successor to tiny_id
, which allows the creation of tightly-packed alphanumeric strings. tiny_id
turned out to be difficult to use in a distributed environment because its state needs to be synchronized across every node that needs to generate IDs. Rather than building distributed functionality into a short ID generator, block_id
provides a way of turning a sequential ID generator into a string ID generator by creating a one-to-one mapping between integers and random-looking short strings. That way, anything system of generating sequential numeric IDs (for example, a database's sequence generator) can be turned into a system for generating random-looking string IDs.
```rust use block_id::{Alphabet, BlockId};
fn main() {
// The alphabet determines the set of valid characters in an ID.
// For convenience, we include some common alphabets like alphanumeric
.
let alphabet = Alphabet::alphanumeric();
// The generator takes a u128 as a seed.
let seed = 1234;
// The length of a generated code. This is really a _minimum_ length; larger numbers
// will be converted to longer codes since that's the only way to avoid collisions.
let length = 4;
// A small amount of pre-caching work happens when we create the BlockId instance,
// so it's good to re-use the same generator where possible.
let generator = BlockId::new(alphabet, seed, length);
// Now that we have a generator, we can turn numbers into short IDs.
assert_eq!("In4R", &generator.encode_string(0));
assert_eq!("4A7N", &generator.encode_string(440));
assert_eq!("tSp9", &generator.encode_string(441));
assert_eq!("6z6y", &generator.encode_string(442));
assert_eq!("ft0M", &generator.encode_string(443));
// When we've exhausted all 4-digit codes, we simply move on to 5-digit codes.
assert_eq!("YeyKs", &generator.encode_string(123456789));
// ...and so on.
assert_eq!("pFbrRf", &generator.encode_string(1234567890));
// Codes are reversible, assuming we have the seed they were generated with.
assert_eq!(1234567890, generator.decode_string("pFbrRf"));
} ```
block_id
applies a pipeline of reversible transformations on a data in order to turn it into a string.
BlockId
constructor.The number of rounds is the same as the number of digits in the base-N representation. This gives every digit a chance to influence every other digit.
block_id
is designed to make it easy for a human to distinguish between two sequential codes, not to make it impossible for an adversary to reverse. It should not be considered cryptographically secure.