Skip to main content

pi_rand/
lib.rs

1use std::convert::TryInto;
2use std::time::SystemTime;
3use rand_core::{SeedableRng, RngCore};
4use rand_chacha::ChaCha12Rng;
5
6///
7/// 密码学安全的随机数生成器
8///
9pub struct SecureRng(ChaCha12Rng);
10
11impl Default for SecureRng {
12    /// 使用当前UTC做为种子,创建密码学安全的随机数生成器
13    fn default() -> Self {
14        let time = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
15        Self::with_seed(time.as_millis() as u64)
16    }
17}
18
19impl SecureRng {
20    /// 使用种子创建密码学安全的随机数生成器
21    pub fn with_seed(seed: u64) -> Self {
22        let inner = ChaCha12Rng::seed_from_u64(seed);
23        SecureRng(inner)
24    }
25
26    /// 使用指定密钥异或加密的种子,创建密码学安全的随机数生成器
27    pub fn with_safe_seed<S, K>(encrypted: S, key: K) -> Self
28    where S: AsRef<[u8]>,
29          K: AsRef<[u8]>,
30    {
31        let unencrypted = xor_encrypt(encrypted, key).unwrap();
32        let seed = u64::from_le_bytes(unencrypted.as_slice().try_into().unwrap());
33        Self::with_seed(seed)
34    }
35
36    /// 使用指定密钥异或加密并混淆的种子,创建密码学安全的随机数生成器
37    pub fn with_confusion_seed<S, K>(encrypted: S, key: K) -> Self
38    where S: AsRef<[u8]>,
39          K: AsRef<[u8]>,
40    {
41        let unencrypted = xor_unencrypt_clarity(encrypted, key).unwrap();
42        let seed = u64::from_le_bytes(unencrypted.as_slice().try_into().unwrap());
43        Self::with_seed(seed)
44    }
45
46    /// 获取一个u32的随机数
47    #[inline]
48    pub fn get_u32(&mut self) -> u32 {
49        self.0.next_u32()
50    }
51
52    /// 获取一个u64的随机数
53    #[inline]
54    pub fn get_u64(&mut self) -> u64 {
55        self.0.next_u64()
56    }
57}
58
59///
60/// 使用指定的密钥为指定的数据异或加解密
61///
62#[inline]
63pub fn xor_encrypt<T, K>(data: T, key: K) -> Result<Vec<u8>, ()>
64where
65    T: AsRef<[u8]>,
66    K: AsRef<[u8]>,
67{
68    let data = data.as_ref();
69    let key = key.as_ref();
70
71    if key.as_ref().len() < 8 {
72        //密钥长度太小,则立即返回错误
73        return Err(());
74    }
75
76    let encrypted = data
77        .iter()
78        .enumerate()
79        .map(|(i, &byte)| byte ^ key[i % key.len()])
80        .collect();
81
82    Ok(encrypted)
83}
84
85///
86/// 使用指定的密钥为指定的数据异或加解密并混淆
87///
88#[inline]
89pub fn xor_encrypt_confusion<T, K>(data: T, key: K) -> Result<Vec<u8>, ()>
90where
91    T: AsRef<[u8]>,
92    K: AsRef<[u8]>,
93{
94    let encrypt = xor_encrypt(data, key)?;
95
96    let len = encrypt.len();
97    if len % 2 != 0 {
98        //长度为奇数,则立即返回错误
99        return Err(());
100    }
101
102    let half_len = len / 2;
103    let mut confused = Vec::with_capacity(len);
104    confused.resize(len, 0);
105    for i in 0..len {
106        if i % 2 != 0 {
107            confused[i] = encrypt[i];
108            continue;
109        } else if i < half_len {
110            let j = i + half_len;
111            confused[j] = encrypt[i];
112            confused[i] = encrypt[j];
113        }
114    }
115
116    Ok(confused)
117}
118
119///
120/// 使用指定的密钥为指定的数据明确并异或解密
121///
122#[inline]
123pub fn xor_unencrypt_clarity<T, K>(data: T, key: K) -> Result<Vec<u8>, ()>
124where
125    T: AsRef<[u8]>,
126    K: AsRef<[u8]>,
127{
128    let encrypt = data.as_ref();
129    let len = encrypt.len();
130    if len % 2 != 0 {
131        //长度为奇数,则立即返回错误
132        return Err(());
133    }
134
135    let half_len = len / 2;
136    let mut clarified = Vec::with_capacity(len);
137    clarified.resize(len, 0);
138    for i in 0..len {
139        if i % 2 != 0 {
140            clarified[i] = encrypt[i];
141            continue;
142        } else if i < half_len {
143            let j = i + half_len;
144            clarified[j] = encrypt[i];
145            clarified[i] = encrypt[j];
146        }
147    }
148
149    let unencrypt = xor_encrypt(clarified, key)?;
150
151    Ok(unencrypt)
152}
153