1use 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}