diff --git a/README.md b/README.md index f39e479..9842bd1 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Rust 中可以使用的常用辅助功能工具箱。主要配备以下功能: - 唯一序列号生成器 - [ ] 改进版雪花 ID 生成器(短主机精简日期版) - [x] UUID 生成器 - - [ ] short UUID 生成器 + - [x] short UUID 生成器 - 签名算法 - [ ] RSA 签名算法 - 验证码生成器 diff --git a/src/serial_code/mod.rs b/src/serial_code/mod.rs index ab9b9da..98ae1f0 100644 --- a/src/serial_code/mod.rs +++ b/src/serial_code/mod.rs @@ -3,3 +3,46 @@ pub mod uuid { Box::from(uuid::Uuid::new_v4().to_string()) } } + +pub mod short_uuid { + const STR_SRC: &str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + pub fn new(length: i16) -> Box { + let length = if length < 2 { + 2 + } else if length > 128 { + 128 + } else { + length + }; + let choices = STR_SRC.as_bytes(); + let mut uuid = uuid::Uuid::new_v4().as_u128(); + let mut mask = 0_u128; + let mut result_bits: Vec = Vec::new(); + let (mask_length, last_mask_length) = if 128 % length == 0 { + (128 / length, 0) + } else { + (128 / length + 1, 128 / length - 128 % length) + }; + for _ in 1..mask_length { + mask = (mask << 1) | 0b1; + } + if last_mask_length > 0 { + let mut last_mask = 0_u128; + for _ in 1..last_mask_length { + last_mask = (last_mask << 1) | 0b1; + } + result_bits.push(((uuid & last_mask) as i64) % choices.len() as i64); + uuid = uuid >> last_mask_length; + } + for _ in 0..(length - if last_mask_length > 0 { 1 } else { 0 }) { + result_bits.push(((uuid & mask) as i64) % choices.len() as i64); + uuid = uuid >> mask_length; + } + let mut code: Vec = Vec::new(); + result_bits.reverse(); + for i in result_bits { + code.push(String::from_utf8(vec![choices[i as usize]]).unwrap()); + } + Box::from(code.join("")) + } +} diff --git a/tests/serial_codes.rs b/tests/serial_codes.rs new file mode 100644 index 0000000..a0bdc84 --- /dev/null +++ b/tests/serial_codes.rs @@ -0,0 +1,20 @@ +#[cfg(test)] +mod uuid_test { + #[test] + fn gen_uuid() { + let uuid = rs_toolbox::serial_code::uuid::new(); + println!("{}", uuid); + } +} + +#[cfg(test)] +mod short_uuid_test { + #[test] + fn gen_short() { + let short_uuid = rs_toolbox::serial_code::short_uuid::new(10); + println!("{}", short_uuid); + if short_uuid.len() != 10 { + panic!("short_uuid length is not enough"); + } + } +}