1#[derive(Debug, Clone)]
20pub struct Base64Encoder;
21
22impl Base64Encoder {
23 pub fn encode(input: &[u8]) -> String {
25 let input_length: usize = input.len();
26 if input_length == 0 {
27 return "".to_string();
28 }
29 let valid_length: usize = match input_length % 3 {
30 0 => input_length / 3 * 4,
31 1 => input_length / 3 * 4 + 2,
32 2 => input_length / 3 * 4 + 3,
33 _ => panic!(""),
34 };
35 const TABLE: &[u8] =
36 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".as_bytes();
37 let mut output: Vec<u8> = Vec::with_capacity(input_length * 2 + 1);
38 let m: usize = valid_length / 4;
39 for x in 0..m {
40 let y0: usize = x * 3 + 0;
45 let y1: usize = x * 3 + 1;
46 let y2: usize = x * 3 + 2;
47 let mut v1: u8;
48 let mut v2: u8;
49 v1 = (input[y0] & 0b11111100) >> 2;
50 v2 = 0;
51 output.push(TABLE[(v1 | v2) as usize]);
52 v1 = (input[y0] & 0b00000011) << 4;
53 v2 = (input[y1] & 0b11110000) >> 4;
54 output.push(TABLE[(v1 | v2) as usize]);
55 v1 = (input[y1] & 0b00001111) << 2;
56 v2 = (input[y2] & 0b11000000) >> 6;
57 output.push(TABLE[(v1 | v2) as usize]);
58 v1 = (input[y2] & 0b00111111) >> 0;
59 v2 = 0;
60 output.push(TABLE[(v1 | v2) as usize]);
61 }
62 let y0: usize = m * 3 + 0;
67 let y1: usize = m * 3 + 1;
68 let mut v1: u8;
70 let mut v2: u8;
71 if input_length % 3 == 1 {
72 v1 = (input[y0] & 0b11111100) >> 2;
73 v2 = 0;
74 output.push(TABLE[(v1 | v2) as usize]);
75 v1 = (input[y0] & 0b00000011) << 4;
76 v2 = 0;
77 output.push(TABLE[(v1 | v2) as usize]);
78 output.push(b'=');
79 output.push(b'=');
80 } else if input_length % 3 == 2 {
81 v1 = (input[y0] & 0b11111100) >> 2;
82 v2 = 0;
83 output.push(TABLE[(v1 | v2) as usize]);
84 v1 = (input[y0] & 0b00000011) << 4;
85 v2 = (input[y1] & 0b11110000) >> 4;
86 output.push(TABLE[(v1 | v2) as usize]);
87 v1 = (input[y1] & 0b00001111) << 2;
88 v2 = 0;
89 output.push(TABLE[(v1 | v2) as usize]);
90 output.push(b'=');
91 }
92 let output: String = String::from_utf8(output).unwrap();
93 return output;
94 }
95
96 pub fn decode(input: &str) -> Result<Vec<u8>, String> {
101 let input: String = input.to_string();
102 const TABLE: [u8; 0x100] = [
103 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
104 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
105 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56,
106 57, 58, 59, 60, 61, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
107 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255,
108 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
109 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
110 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
111 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
112 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
113 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
114 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
115 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
116 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
117 255, 255,
118 ];
119 let length: usize = input.len();
120 if length == 0 {
121 return Ok(Vec::<u8>::new());
122 }
123 if length % 4 != 0 {
124 return Err(iceyee_error::a!("无效的长度"));
125 }
126 let input_data: &[u8] = input.as_bytes();
127 for x in 0..input_data.len() {
128 let c: u8 = input_data[x];
129 if TABLE[c as usize] != 255 || c == b'=' && input_data.len() <= x + 2 {
130 } else {
132 return Err(iceyee_error::a!("出现未预期的字符"));
133 }
134 }
135 let new_length: usize = if input_data[input_data.len() - 2] == b'=' {
136 (length - 2) / 4 * 3 + 1
137 } else if input_data[input_data.len() - 1] == b'=' {
138 (length - 1) / 4 * 3 + 2
139 } else {
140 length / 4 * 3
141 };
142 let mut output: Vec<u8> = Vec::new();
143 let m: usize = new_length / 3;
144 for x in 0..m {
145 let y0: usize = x * 4 + 0;
149 let y1: usize = x * 4 + 1;
150 let y2: usize = x * 4 + 2;
151 let y3: usize = x * 4 + 3;
152 let mut v1: u8;
153 let mut v2: u8;
154 v1 = (TABLE[input_data[y0] as usize] & 0b00111111) << 2;
155 v2 = (TABLE[input_data[y1] as usize] & 0b00110000) >> 4;
156 output.push(v1 | v2);
157 v1 = (TABLE[input_data[y1] as usize] & 0b00001111) << 4;
158 v2 = (TABLE[input_data[y2] as usize] & 0b00111100) >> 2;
159 output.push(v1 | v2);
160 v1 = (TABLE[input_data[y2] as usize] & 0b00000011) << 6;
161 v2 = (TABLE[input_data[y3] as usize] & 0b00111111) >> 0;
162 output.push(v1 | v2);
163 }
164 let y0: usize = m * 4 + 0;
168 let y1: usize = m * 4 + 1;
169 let y2: usize = m * 4 + 2;
170 let mut v1: u8;
172 let mut v2: u8;
173 if new_length % 3 == 1 {
174 v1 = (TABLE[input_data[y0] as usize] & 0b00111111) << 2;
175 v2 = (TABLE[input_data[y1] as usize] & 0b00110000) >> 4;
176 output.push(v1 | v2);
177 } else if new_length % 3 == 2 {
178 v1 = (TABLE[input_data[y0] as usize] & 0b00111111) << 2;
179 v2 = (TABLE[input_data[y1] as usize] & 0b00110000) >> 4;
180 output.push(v1 | v2);
181 v1 = (TABLE[input_data[y1] as usize] & 0b00001111) << 4;
182 v2 = (TABLE[input_data[y2] as usize] & 0b00111100) >> 2;
183 output.push(v1 | v2);
184 }
185 return Ok(output);
186 }
187}
188
189#[derive(Debug, Clone)]
191pub struct HexEncoder;
192
193impl HexEncoder {
194 pub fn encode(input: &[u8]) -> String {
196 static TABLE: [char; 16] = [
197 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
198 ];
199 let mut output: String = String::new();
200 for x in input {
201 let high: u8 = (x >> 4) & 0x0F;
202 let low: u8 = (x >> 0) & 0x0F;
203 output.push(TABLE[high as usize]);
204 output.push(TABLE[low as usize]);
205 }
206 return output;
207 }
208
209 pub fn decode(input: &str) -> Result<Vec<u8>, String> {
214 let input: String = input.to_string();
215 let length: usize = input.len();
216 if length % 2 != 0 {
217 return Err(iceyee_error::a!("无效的长度"));
218 }
219 let mut output: Vec<u8> = Vec::new();
220 let input: &[u8] = input.as_bytes();
221 let mut high: u8;
222 let mut low: u8;
223 for x in 0..(length / 2) {
224 match input[x * 2] {
225 b'0'..=b'9' => {
226 high = input[x * 2] - b'0';
227 }
228 b'a'..=b'f' => {
229 high = input[x * 2] - b'a' + 10;
230 }
231 b'A'..=b'F' => {
232 high = input[x * 2] - b'A' + 10;
233 }
234 _ => return Err(iceyee_error::a!("出现未预期的字符")),
235 }
236 match input[x * 2 + 1] {
237 b'0'..=b'9' => {
238 low = input[x * 2 + 1] - b'0';
239 }
240 b'a'..=b'f' => {
241 low = input[x * 2 + 1] - b'a' + 10;
242 }
243 b'A'..=b'F' => {
244 low = input[x * 2 + 1] - b'A' + 10;
245 }
246 _ => return Err(iceyee_error::a!("出现未预期的字符")),
247 }
248 let b: u8 = (high << 4) | (low << 0);
249 output.push(b);
250 }
251 return Ok(output);
252 }
253
254 pub fn encode_number(mut input: u64) -> String {
256 static TABLE: [char; 16] = [
257 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
258 ];
259 if input == 0 {
260 return "0".to_string();
261 }
262 let mut output: Vec<u8> = Vec::new();
263 while input != 0 {
264 let digit: usize = (input & 0xF) as usize;
265 output.push(TABLE[digit] as u8);
266 input = input >> 4;
267 let digit: usize = (input & 0xF) as usize;
268 output.push(TABLE[digit] as u8);
269 input = input >> 4;
270 }
271 output.reverse();
272 return String::from_utf8(output).unwrap();
273 }
274
275 pub fn decode_number(input: &str) -> Result<u64, String> {
280 let v1: &[u8] = input.as_bytes();
281 if 16 < v1.len() {
282 return Err(iceyee_error::a!("长度超过16"));
284 }
285 let mut output: u64 = 0;
286 for x in 0..v1.len() {
287 match v1[x] {
288 b'0'..=b'9' => {
289 output <<= 4;
290 output |= (v1[x] - b'0') as u64;
291 }
292 b'A'..=b'F' => {
293 output <<= 4;
294 output |= (v1[x] - b'A' + 10) as u64;
295 }
296 b'a'..=b'f' => {
297 output <<= 4;
298 output |= (v1[x] - b'a' + 10) as u64;
299 }
300 _ => {
301 return Err(iceyee_error::a!("出现未预期的字符"));
302 }
303 }
304 }
305 return Ok(output);
306 }
307}
308
309#[derive(Debug, Clone)]
312pub struct UrlEncoder;
313
314impl UrlEncoder {
315 pub fn encode(input: &str) -> String {
317 let input: String = input.to_string();
318 static TABLE: [char; 16] = [
319 '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
320 ];
321 let mut output: String = String::new();
322 let input: &[u8] = input.as_bytes();
323 for x in input {
324 if *x == b' ' {
325 output.push('+');
326 } else if x.is_ascii_alphanumeric() || "$-_.".contains(*x as char) {
327 output.push(*x as char);
328 } else {
329 let high: u8 = (*x >> 4) & 0x0F;
330 let low: u8 = (*x >> 0) & 0x0F;
331 output.push('%');
332 output.push(TABLE[high as usize]);
333 output.push(TABLE[low as usize]);
334 }
335 }
336 return output;
337 }
338
339 pub fn decode(cipher: &str) -> Result<String, String> {
344 let cipher: String = cipher.to_string();
345 enum Status {
346 Normal,
347 High,
348 Low,
349 }
350 let mut plain: Vec<u8> = Vec::new();
351 let cipher: &[u8] = cipher.as_bytes();
352 let mut status: Status = Status::Normal;
353 let mut high: u8 = 0;
354 let mut low: u8;
355 for x in cipher {
356 match status {
357 Status::Normal => match *x {
358 b'%' => status = Status::High,
359 b'+' => plain.push(b' '),
360 _ => plain.push(*x),
361 },
362 Status::High => match *x {
363 b'0'..=b'9' => {
364 status = Status::Low;
365 high = *x - b'0';
366 }
367 b'a'..=b'f' => {
368 status = Status::Low;
369 high = *x - b'a' + 10;
370 }
371 b'A'..=b'F' => {
372 status = Status::Low;
373 high = *x - b'A' + 10;
374 }
375 _ => return Err(iceyee_error::a!("错误的格式")),
376 },
377 Status::Low => match *x {
378 b'0'..=b'9' => {
379 status = Status::Normal;
380 low = *x - b'0';
381 plain.push((high << 4) | (low << 0));
382 }
383 b'a'..=b'f' => {
384 status = Status::Normal;
385 low = *x - b'a' + 10;
386 plain.push((high << 4) | (low << 0));
387 }
388 b'A'..=b'F' => {
389 status = Status::Normal;
390 low = *x - b'A' + 10;
391 plain.push((high << 4) | (low << 0));
392 }
393 _ => return Err(iceyee_error::a!("错误的格式")),
394 },
395 }
396 }
397 match status {
398 Status::Normal => {}
399 _ => return Err(iceyee_error::a!("错误的格式")),
400 }
401 let plain: String =
402 String::from_utf8(plain).map_err(|_| iceyee_error::a!("内容不是UTF-8编码"))?;
403 return Ok(plain);
404 }
405}
406
407