namerena-rs/src/name.rs

150 lines
3.1 KiB
Rust
Raw Normal View History

2024-02-28 21:49:09 +08:00
use tracing::warn;
use crate::name;
2024-02-28 19:04:57 +08:00
pub fn median(x: u8, y: u8, z: u8) -> u8 {
// std::max(std::min(x, y), std::min(std::max(x, y), z))
x.max(y).max(x.min(y).min(z))
}
2024-02-28 21:49:09 +08:00
#[derive(Debug, Clone)]
pub struct Namer {
pub name: String,
pub team: String,
pub val: [u8; 256],
pub name_base: [u8; 128],
pub name_bytes: [u8; 256],
pub team_bytes: [u8; 256],
pub name_prop: [u8; 8],
pub skl_id: [u8; 40],
pub skl_freq: [u8; 40],
2024-02-28 19:04:57 +08:00
}
2024-02-28 19:18:30 +08:00
2024-02-28 21:49:09 +08:00
impl Namer {
pub fn new(raw_name: &String) -> Option<Self> {
let mut val = [0_u8; 256];
for i in 0..256 {
val[i] = i as u8;
}
let mut name_base = [0_u8; 128];
let mut name_prop = [0_u8; 8];
let mut skl_id = [0_u8; 40];
let mut skl_freq = [0_u8; 40];
2024-02-28 19:18:30 +08:00
2024-02-28 21:49:09 +08:00
// name@team
// name
let (name, team) = raw_name.split_once('@').unwrap_or((raw_name, ""));
// len < 256
if name.len() > 255 {
warn!("Name too long({}): {}", name.len(), name);
return None;
}
let name_len = name.len();
if team.len() > 255 {
warn!("Team too long({}): {}", team.len(), team);
return None;
}
let team_len = team.len();
2024-02-28 19:18:30 +08:00
2024-02-28 21:49:09 +08:00
let name_bytes = name.as_bytes();
let team_bytes = team.as_bytes();
// 转到 256 长度 的 u8 数组
let name_bytes = {
let mut bytes = [0_u8; 256];
for i in 0..name_len {
bytes[i] = name_bytes[i];
}
bytes
};
let team_bytes = {
let mut bytes = [0_u8; 256];
for i in 0..team_len {
bytes[i] = team_bytes[i];
}
bytes
};
2024-02-28 19:18:30 +08:00
2024-02-28 21:49:09 +08:00
let mut s = 0_u32;
for i in 0..256 {
s += name_bytes[i] as u32 + val[i] as u32;
s %= 256;
let tmp = val[i];
val[i] = val[s as usize];
val[s as usize] = tmp;
}
for _ in 0..2 {
s = 0;
for j in 0..256 {
s += name_bytes[j % name_len] as u32 + val[j] as u32;
s %= 256;
let tmp = val[j];
val[j] = val[s as usize];
val[s as usize] = tmp;
}
}
s = 0;
for i in 0..256 {
let m = ((val[i] as u32 * 181 + 160) % 256) as u8;
if m >= 89 && m < 217 {
name_base[s as usize] = m & 63;
}
}
2024-02-28 19:18:30 +08:00
2024-02-28 21:49:09 +08:00
let mut prop_cnt = 0;
let mut r = name_base[0..32].to_vec();
for i in (10..31).step_by(3) {
r[i..i + 3].sort();
name_prop[prop_cnt] = r[i + 1];
prop_cnt += 1;
}
r[0..10].sort();
name_prop[prop_cnt] = 154;
prop_cnt += 1;
for i in 3..7 {
name_prop[prop_cnt - 1] += r[i];
}
for i in 0..7 {
name_prop[i] += 36;
}
2024-02-28 19:18:30 +08:00
2024-02-28 21:49:09 +08:00
Some(Self {
name: name.to_string(),
team: team.to_string(),
val,
name_base,
name_bytes,
team_bytes,
name_prop,
skl_id,
skl_freq,
})
}
2024-02-28 19:18:30 +08:00
2024-02-28 21:49:09 +08:00
pub fn name_len(&self) -> usize { self.name.len() + 1 }
2024-02-28 19:18:30 +08:00
2024-02-28 21:49:09 +08:00
pub fn team_len(&self) -> usize { self.team.len() + 1 }
2024-02-28 19:04:57 +08:00
}
2024-02-28 21:49:09 +08:00
#[cfg(test)]
mod test {
use super::*;
#[test]
fn basic_new_test() {
let namer = Namer::new(&"x@x".to_string());
assert!(namer.is_some());
let namer = namer.unwrap();
// println!("{:#?}", namer);
assert_eq!(namer.name, "x");
assert_eq!(namer.team, "x");
println!("val: {:?}", namer.val);
println!("name_base: {:?}", namer.name_base);
println!("name_bytes: {:?}", namer.name_bytes);
println!("team_bytes: {:?}", namer.team_bytes);
println!("name_prop: {:?}", namer.name_prop);
println!("skl_id: {:?}", namer.skl_id);
println!("skl_freq: {:?}", namer.skl_freq);
}
2024-02-28 19:04:57 +08:00
}