起因 发现简书一类的网站资源 ID 很短不知道如何实现 如 https://www.jianshu.com/p/4a8939c48cd4 这个 12 位的 然后就考虑到雪花法但生成结果是:6887650413378670482 近 20 位数字,就考虑是否有其它处理方式 主要目的是想把雪花算法生成的值变得更短 如 6887650413378670482 转换成更短小的格式 16 或 12 位数字字符串 实现 经过多方查找现定使用雪花算法生成 ID 再转为 36 进制的 13 位小写字母加数字格式 进制转换参考 python 实现方式: https://blog.csdn.net/dutsoft/article/details/79076327 初级进制转换 /// 10 进制转为 11 - 62 进制 36 进制前是小写 fn base_n(num: u64, n: i32) -> String { let num_rep: HashMap<i32, char> = HashMap::from([ (10, 'a'), (11, 'b'), (12, 'c'), (13, 'd'), (14, 'e'), (15, 'f'), (16, 'g'), (17, 'h'), (18, 'i'), (19, 'j'), (20, 'k'), (21, 'l'), (22, 'm'), (23, 'n'), (24, 'o'), (25, 'p'), (26, 'q'), (27, 'r'), (28, 's'), (29, 't'), (30, 'u'), (31, 'v'), (32, 'w'), (33, 'x'), (34, 'y'), (35, 'z'), (36, 'A'), (37, 'B'), (38, 'C'), (39, 'D'), (40, 'E'), (41, 'F'), (42, 'G'), (43, 'H'), (44, 'I'), (45, 'J'), (46, 'K'), (47, 'L'), (48, 'M'), (49, 'N'), (50, 'O'), (51, 'P'), (52, 'Q'), (53, 'R'), (54, 'S'), (55, 'T'), (56, 'U'), (57, 'V'), (58, 'W'), (59, 'X'), (60, 'Y'), (61, 'Z') ]); let mut new_num_string = String::from(""); let mut current: u64 = num; while current != 0 { let remainder = (current % (n as u64)) as i32; let mut remainder_string: String; if remainder > 9 && remainder < 62 { remainder_string = format!("{}", num_rep.get(&remainder).unwrap()); } else { remainder_string = format!("{}", remainder); } new_num_string = format!("{}{}", remainder_string, new_num_string); current = current / (n as u64); } new_num_string } #[cfg(test)] mod tests { use super::base_n; #[test] fn test_base_35() { let num = 6887946670030594043; assert_eq!(base_n(num, 35), "21bx54naqlu18"); } /// 测试16进制结果是否和标准库一致 #[test] fn test_base_16() { let num = 6887946670030594043; let stand_val = format!("{:x}", num); assert_eq!(base_n(num, 16), stand_val); } } 进阶版进制转换 const ALL_CHARS: &'static str = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_"; /// 进阶版 10 进制转 11 - 64 进制 /// /// ``` /// let raw_id = 6888076346770202619; /// assert_eq!(base_10_to_n(raw_id, 36), "1gbyra5idyk8r"); /// ``` fn base_10_to_n(num: u64, radix: u32) -> String { if num == 0 { return String::from("0"); } let base = base_10_to_n(num / (radix as u64), radix); let start = base.strip_prefix("0").unwrap_or(base.as_str()); let end = match ALL_CHARS.chars().nth((num % (radix as u64)) as usize) { Some(data) => String::from(data), _ => String::from(""), }; format!("{}{}", start, end) } /// 11 - 64 进制解析为 10 进制 /// /// ``` /// let id = "1gbyra5idyk8r"; /// assert_eq!(base_n_to_10(id, 36), 6888076346770202619); /// ``` fn base_n_to_10(num_str: &str, radix: u32) -> u128 { let mut result: u128 = 0; for i in 0..num_str.len() { result *= radix as u128; let target_char = num_str.chars().nth(i).unwrap_or('0'); let data = ALL_CHARS.chars().position(|i| i == target_char).unwrap_or(0); result += data as u128; } result } 雪花算法终极方案 use snowflake::SnowflakeIdBucket; /// 生成雪花算法ID 结果转为36进制 fn get_snow_id(radix: u32) -> (String, u64) { let mut b = SnowflakeIdBucket::new(1, 1); let raw_id = b.get_id() as u64; (base_10_to_n(raw_id, radix), raw_id) } 测试雪花算法 ID 生成及进制解析 use snowflake::SnowflakeIdBucket; use std::thread::sleep; use std::time::Duration; fn test_decode_snow() { // 结果转为 36 进制 let radix = 36; for _ in 1..20 { let (id, raw_id) = get_snow_id(radix); // 进制转换 let decode_data = base_n_to_10(&id, radix); // 输出原始ID 36进制ID 解析为10进制结果 println!("raw_id: {} id: {} de: {}", raw_id, id, decode_data); // 暂停1毫秒 sleep(Duration::from_millis(1)); } } 打印如下结果 raw_id: 6888082659701039099 id: 1gbytipmpzgmz de: 6888082659701039099 raw_id: 6888082659709427707 id: 1gbytipmuz9bv de: 6888082659709427707 raw_id: 6888082659772342267 id: 1gbytipnwfqij de: 6888082659772342267 raw_id: 6888082659839451131 id: 1gbytipp0e41n de: 6888082659839451131 raw_id: 6888082659902365691 id: 1gbytipq1ul8b de: 6888082659902365691 raw_id: 6888082659969474555 id: 1gbytipr5syrf de: 6888082659969474555 raw_id: 6888082660032389115 id: 1gbytips79fy3 de: 6888082660032389115 raw_id: 6888082660099497979 id: 1gbytiptb7th7 de: 6888082660099497979 raw_id: 6888082660162412539 id: 1gbytipucoanv de: 6888082660162412539 raw_id: 6888082660225327099 id: 1gbytipve4ruj de: 6888082660225327099 若有更好的实现方式,欢迎评论指导。