5 个版本
0.2.1 | 2023年4月27日 |
---|---|
0.2.0 | 2023年4月12日 |
0.1.2 | 2022年4月9日 |
0.1.1 | 2022年4月1日 |
0.1.0 | 2022年4月1日 |
#10 in #id-generator
438 每月下载量
用于 2 crates
27KB
596 行
block-id
block-id
是一个 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!(Some("wjweA".to_string()), generator.encode_string(0));
assert_eq!(Some("ZxJrE".to_string()), generator.encode_string(1));
assert_eq!(Some("3e0IT".to_string()), generator.encode_string(2));
// String to number.
assert_eq!(Some(2), generator.decode_string("3e0IT"));
}
简介
看似随机的字母数字字符串通常用于替代顺序数字 ID,以供用户界面使用。这有几个优点
- 字符串标识符通常在视觉上明显区分,即使它们在序列中相邻生成。
- 更大的字母表的信息密度更高,允许更短的代码。
- 顺序标识符会揭示有关顺序和对象创建速率的不必要信息,这些信息你可能不希望揭示。
block-id
是 tiny_id
的后续产品,它允许创建紧密排列的字母数字字符串。由于它的状态需要同步到每个需要生成 ID 的节点,因此 tiny_id
在分布式环境中使用起来很困难。而不是在短 ID 生成器中构建分布式功能,block-id
通过创建整数和看似随机的简短字符串之间的一对一映射,提供了一种将顺序 ID 生成器转换为字符串 ID 生成器的方法。这样,任何生成顺序数字 ID 的系统(例如,数据库的序列生成器)都可以转换为生成看似随机的字符串 ID 的系统。
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!(Some("In4R".to_string()), generator.encode_string(0));
assert_eq!(Some("4A7N".to_string()), generator.encode_string(440));
assert_eq!(Some("tSp9".to_string()), generator.encode_string(441));
assert_eq!(Some("6z6y".to_string()), generator.encode_string(442));
assert_eq!(Some("ft0M".to_string()), generator.encode_string(443));
// When we've exhausted all 4-digit codes, we simply move on to 5-digit codes.
assert_eq!(Some("YeyKs".to_string()), generator.encode_string(123456789));
// ...and so on.
assert_eq!(Some("pFbrRf".to_string()), generator.encode_string(1234567890));
// Codes are reversible, assuming we have the seed they were generated with.
assert_eq!(Some(1234567890), generator.decode_string("pFbrRf"));
}
工作原理
block-id
对数据进行一系列可逆变换,以将其转换为字符串。
- 基数转换 将输入整数转换为基-N 表示,其中 N 是所需输出字母表中的字符数。
- 包括以下步骤
- 排列 将 N 到 N 的映射应用于基-N 表示的每个数字。排列由传递给
BlockId
构造函数的随机种子生成。 - 级联 对基-N 表示执行从左到右的累积和,模 N。
- 旋转 将基-N 表示中的第一个数字移动到最后一个数字,并将所有其他数字向左移动一位。
- 排列 将 N 到 N 的映射应用于基-N 表示的每个数字。排列由传递给
- 字母化 将基-N 表示的每个数字转换为构造时提供的字母表中的“字母”。
轮数与基-N 表示中的数字数相同。这使得每个数字都有机会影响其他所有数字。
安全性
block-id
的设计是为了让人类更容易区分两个连续的代码,而不是 使敌手无法反向解析。它不应该被认为具有密码学安全性。
依赖关系
~345KB