md5mix/
lib.rs

1//! # md5 混淆加解密数字
2//!
3//! md5 混淆加解密数字到字符串,解析字符串到数字,抄袭php的一个加密算法,加密算法名字不明
4//! 
5/// 
6/// 
7/// # Examples
8///
9/// ```
10///let sign_str = "xxxxxxxx";
11///let md5mix_obj = md5mix::Md5mix::new(sign_str);
12///let result = md5mix_obj.encode(1000898);
13///let str = result.unwrap();
14///println!("str:{}", &str);
15
16///let result = md5mix_obj.decode(&str);
17///let id = result.unwrap();
18///println!("id:{}", id);
19/// ```
20/// 
21// --snip--
22
23
24use crypto::md5::Md5;
25use crypto::digest::Digest;
26
27
28use std::time::SystemTime;
29
30
31pub struct Md5mix<'a>{
32    sign_str: &'a str,
33}
34
35impl<'a> Md5mix<'a> {
36    pub fn new(s: &'a str) -> Md5mix {
37        Self { sign_str: s }
38    }
39
40    pub fn decode(&self, s: &str) -> Result<i32, String> {
41
42        let string = s.replace("-", "+").replace("_", "/").replace(".", "=");
43
44        let ckey_length = 4;
45
46        let ( keya, _keyb) = self.create_key();
47
48        let keyc = &string[..ckey_length];
49
50        let mut hasher = Md5::new();
51        
52        let keyacstr = format!("{}{}", keya, keyc);
53        hasher.input_str(&keyacstr);
54        let keyac = hasher.result_str();
55
56
57        let cryptkey = format!("{}{}", &keya, &keyac);
58
59
60        let string = match base64::decode(&string[ckey_length..]){
61            Ok(s) => s,
62            Err(e) => {
63                return Err(format!("base64.decode err:{:?}", e))
64            }
65        };
66
67
68        let buf = Self::mix(&cryptkey, &string);
69
70
71        let result = match std::str::from_utf8(&buf){
72            Ok(s) => s,
73            Err(e) => {
74                return Err(format!("from_utf8 err:{:?}", e))
75            }
76        };
77
78        let number = &result[26..];
79
80        match number.parse(){
81            Ok(s) => Ok(s),
82            Err(e) => Err(format!("number parse err:{:?}", e)),
83        }
84
85    }
86
87
88    fn mix(cryptkey: &str, string: &[u8]) -> Vec<u8>{
89
90
91        let key_length = cryptkey.len();
92
93        let mut randkey: Vec<i32> = Vec::new();
94        for i in 0..256 {
95            let index = i % key_length;
96            let chars = &cryptkey[index..index+1];
97
98            let ascii = chars.as_bytes();
99            let ascii = ascii.to_ascii_lowercase();
100
101            randkey.push(ascii[0] as i32);
102
103        }
104
105
106
107        let mut box_vec: Vec<i32> = Vec::new();
108        for i in 0..256 {
109            box_vec.push(i);
110        }
111
112        let mut j: i32 = 0;
113        for i in 0..256 {
114            j = (j + box_vec[i] + randkey[i]) % 256;
115            let tmp = box_vec[i];
116            box_vec[i] = box_vec[j as usize];
117            box_vec[j as usize] = tmp;
118        }
119
120
121
122        let mut a = 0;
123        let mut j = 0;
124        
125
126        let mut buf: Vec<u8> = vec![];
127
128        for &item in string.into_iter(){
129            a = (a + 1) % 256;
130            
131            j = (j + box_vec[a]) %256;
132
133            let tmp = box_vec[a];
134
135            box_vec[a] = box_vec[j as usize];
136            box_vec[j as usize] = tmp;
137        
138            let stringord = item as i32;
139
140            let b = (box_vec[a] + box_vec[j as usize]) % 256;
141
142            let chr_num =  stringord ^ box_vec[b as usize];
143
144            buf.push(chr_num as u8);
145
146        };
147
148        buf
149
150    }
151
152
153    fn create_key(&self) -> (String, String) {
154        let mut hasher = Md5::new();
155        hasher.input_str(self.sign_str);
156        let key = hasher.result_str();
157
158
159
160        let mut hasher = Md5::new();
161        hasher.input_str(&key[..16]);
162        let keya = hasher.result_str();
163
164        let mut hasher = Md5::new();
165        hasher.input_str(&key[16..]);
166        let keyb = hasher.result_str();
167
168        (keya, keyb)
169    }
170
171    pub fn encode(&self, id: i32) -> Result<String, String> {
172
173
174        let ckey_length = 4;
175
176    
177        let (keya, keyb) = self.create_key();
178
179
180
181        let mut hasher = Md5::new();
182        let now = match SystemTime::now().duration_since(SystemTime::UNIX_EPOCH){
183            Ok(s) => s,
184            Err(e) => {
185                let err = format!("SystemTime::now() err {:?}", e);
186                return Err(err);
187            }
188        };
189        hasher.input_str(&now.as_secs().to_string());
190        let keyc = hasher.result_str();
191        let keyc = &keyc[..];
192        let keycstart = keyc.len() - ckey_length;
193        let keyc = &keyc[keycstart..];
194
195
196        let mut hasher = Md5::new();
197        let keyacstr = format!("{}{}", keya, keyc);
198        hasher.input_str(&keyacstr);
199        let keyac = hasher.result_str();
200
201        let cryptkey = format!("{}{}", &keya, &keyac);
202
203
204        let mut hasher = Md5::new();
205        let string = format!("{}{}", id, keyb);
206        hasher.input_str(&string);
207        let string = hasher.result_str();
208
209        let string: &str = &string[..];
210        let string = format!("0000000000{}{}", &string[0..16], id);
211
212
213        let buf = Self::mix(&cryptkey, &string.as_bytes());
214
215        let bs = &base64::encode(buf);
216        let rs = bs.replace("=", "");
217        let rs = format!("{}{}", keyc, rs);
218        let rs = rs.replace("+", "-").replace("/", "_").replace("=", ".");
219
220
221        Ok(rs)
222
223    }
224
225}