codeckit/
lib.rs

1const BASE32_MAP: [&str; 32] = [
2    "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
3    "T", "U", "V", "W", "X", "Y", "Z", "2", "3", "4", "5", "6", "7",
4];
5
6const BASE32_REVERSE_MAP: [u8; 256] = [
7    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
8    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
9    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 255, 255,
10    255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
11    17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
12    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
13    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
14    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
15    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
16    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
17    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
18    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
19    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
20    255,
21];
22
23pub struct Base32;
24
25impl Base32 {
26    /// Encodes the input bytes into a Base32 string.
27    pub fn encode(input: &[u8]) -> String {
28        let mut ret = String::with_capacity(((input.len() + 4) / 5) * 8);
29        let mut flag = 0;
30        let mut prev: u8 = 0;
31
32        for &i in input {
33            match flag {
34                0 => {
35                    let ind = i >> 3;
36                    prev = (i & 0b00000111) << 2;
37                    ret.push_str(BASE32_MAP[ind as usize]);
38                    flag = 1;
39                }
40                1 => {
41                    let ind = prev + (i >> 6);
42                    let ind_1 = (i & 0b00111111) >> 1;
43                    ret.push_str(BASE32_MAP[ind as usize]);
44                    ret.push_str(BASE32_MAP[ind_1 as usize]);
45                    prev = (i & 0b00000001) << 4;
46                    flag = 2;
47                }
48                2 => {
49                    let ind = prev + (i >> 4);
50                    prev = (i & 0b00001111) << 1;
51                    ret.push_str(BASE32_MAP[ind as usize]);
52                    flag = 3;
53                }
54                3 => {
55                    let ind = prev + (i >> 7);
56                    let ind_1 = (i & 0b01111111) >> 2;
57                    ret.push_str(BASE32_MAP[ind as usize]);
58                    ret.push_str(BASE32_MAP[ind_1 as usize]);
59                    prev = (i & 0b00000011) << 3;
60                    flag = 4;
61                }
62                4 => {
63                    let ind = prev + (i >> 5);
64                    let ind_1 = i & 0b00011111;
65                    ret.push_str(BASE32_MAP[ind as usize]);
66                    ret.push_str(BASE32_MAP[ind_1 as usize]);
67                    prev = 0;
68                    flag = 0;
69                }
70                _ => unreachable!(),
71            }
72        }
73
74        ret.push_str(BASE32_MAP[prev as usize]);
75        // add padding if necessary
76        while ret.len() % 8 != 0 {
77            ret.push('=');
78        }
79        ret
80    }
81    /// Decodes a Base32 string into a Vec<u8>.
82    /// This function ignores invalid characters automatically and not returns an error.
83    pub fn decode(input: &str) -> Vec<u8> {
84        let mut ret = Vec::new();
85        let mut prev: u8 = 0;
86        let mut flag = 0;
87
88        for c in input.chars() {
89            if c == '=' {
90                break;
91            }
92            let i_rev = BASE32_REVERSE_MAP[c as usize];
93            // drop invalid characters and 255 means invalid character
94            if i_rev == 255 {
95                continue;
96            }
97            match flag {
98                // i_rev(5bits) => prev
99                0 => {
100                    prev = i_rev << 3;
101                    flag = 1;
102                }
103                // prev(5bits) + i(3bits)
104                // new prev(2bits)
105                1 => {
106                    let ch = prev + (i_rev >> 2);
107                    ret.push(ch);
108                    prev = (i_rev & 0b00000011) << 6;
109                    flag = 2;
110                }
111                // new prev(7bits) = prev(2bits) + i(5bits)
112                2 => {
113                    prev = prev + (i_rev << 1);
114                    flag = 3;
115                }
116                // prev(7bits) + i(1bit)
117                // new prev(4bits)
118                3 => {
119                    let ch = prev + (i_rev >> 4);
120                    ret.push(ch);
121                    prev = (i_rev & 0b00001111) << 4;
122                    flag = 4;
123                }
124                // prev(4bits) + i(4bits)
125                // new prev(1bits)
126                4 => {
127                    let ch = prev + (i_rev >> 1);
128                    ret.push(ch);
129                    prev = (i_rev & 0b00000001) << 7;
130                    flag = 5;
131                }
132                // new prev(6) = prev(1bits) + i(5bits)
133                5 => {
134                    prev = prev + (i_rev << 2);
135                    flag = 6;
136                }
137                // prev(6bits) + i(2bits)
138                // new prev(3bits)
139                6 => {
140                    let ch = prev + (i_rev >> 3);
141                    ret.push(ch);
142                    prev = (i_rev & 0b00000111) << 5;
143                    flag = 7;
144                }
145                // prev(3bits) + i(5bits)
146                // new prev(0bits)
147                7 => {
148                    let ch = prev + i_rev;
149                    ret.push(ch);
150                    prev = 0;
151                    flag = 0;
152                }
153                _ => unreachable!(),
154            }
155        }
156        ret
157    }
158}
159
160const BASE58_MAP: [&str; 58] = [
161    "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "J", "K",
162    "L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e",
163    "f", "g", "h", "i", "j", "k", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y",
164    "z",
165    // 'o', 'l' are omitted to avoid confusion with '0' and '1'
166    // 'O', 'I' are omitted to avoid confusion with '0' and '1'
167    // '0', '1' are omitted to avoid confusion with 'O' and 'I'
168    // '2', '3', ..., '9' are included
169];
170
171const BASE58_REVERSE_MAP: [u8; 256] = [
172    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
173    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
174    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 255, 255,
175    255, 255, 255, 255, 255, 9, 10, 11, 12, 13, 14, 15, 16, 255, 17, 18, 19, 20, 21, 255, 22, 23,
176    24, 25, 26, 27, 28, 29, 30, 31, 32, 255, 255, 255, 255, 255, 255, 33, 34, 35, 36, 37, 38, 39,
177    40, 41, 42, 43, 255, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 255, 255, 255,
178    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
179    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
180    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
181    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
182    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
183    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
184    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
185];
186
187pub struct Base58;
188
189impl Base58 {
190    fn divmod58(num: &[u8]) -> (Vec<u8>, u8) {
191        let mut quotient = Vec::new();
192        let mut remainder: u8 = 0;
193        for &digit in num {
194            let value = (remainder as u32) * 256 + digit as u32;
195            remainder = (value % 58) as u8;
196            quotient.push((value / 58) as u8);
197        }
198        // remove leading zeros
199        while quotient.len() > 1 && quotient[0] == 0 {
200            quotient.remove(0);
201        }
202        (quotient, remainder)
203    }
204    /// Encodes the input bytes into a Base58 string.
205    pub fn encode(input: &[u8]) -> String {
206        let zeros = input.iter().take_while(|&&x| x == 0).count();
207
208        let mut num = input.to_vec();
209        let mut encoded = String::new();
210
211        while !num.iter().all(|&x| x == 0) {
212            let (quotient, remainder) = Self::divmod58(&num);
213            encoded.push_str(BASE58_MAP[remainder as usize]);
214            num = quotient;
215        }
216
217        for _ in 0..zeros {
218            encoded.push('1');
219        }
220
221        encoded = encoded.chars().rev().collect();
222        encoded
223    }
224    /// Decodes a Base58 string into a Vec<u8>.
225    pub fn decode(input: &str) -> Vec<u8> {
226        let mut num = vec![0u8];
227        for c in input.chars() {
228            let val = BASE58_REVERSE_MAP[c as usize];
229            let mut carry = val as u32;
230            if carry == 255 {
231                // invalid character, skip it
232                continue;
233            }
234            for n in num.iter_mut() {
235                let total = *n as u32 * 58 + carry;
236                *n = (total & 0xff) as u8;
237                carry = total >> 8;
238            }
239
240            while carry > 0 {
241                num.push((carry & 0xff) as u8);
242                carry >>= 8;
243            }
244        }
245
246        let mut n_zeros = 0;
247        for c in input.chars() {
248            if c == '1' {
249                n_zeros += 1;
250            } else {
251                break;
252            }
253        }
254        let mut result = vec![0u8; n_zeros];
255        result.extend(num.iter().rev());
256        result
257    }
258}
259
260const BASE62_MAP: [&str; 62] = [
261    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
262    "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b",
263    "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
264    "v", "w", "x", "y", "z",
265];
266
267const BASE62_REVERSE_MAP: [u8; 256] = [
268    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
269    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
270    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255,
271    255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
272    29, 30, 31, 32, 33, 34, 35, 255, 255, 255, 255, 255, 255, 36, 37, 38, 39, 40, 41, 42, 43, 44,
273    45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 255, 255,
274    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
275    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
276    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
277    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
278    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
279    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
280    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
281];
282
283pub struct Base62;
284
285impl Base62 {
286    fn divmod62(num: &[u8]) -> (Vec<u8>, u8) {
287        let mut quotient = Vec::new();
288        let mut remainder: u8 = 0;
289        for &digit in num {
290            let value = (remainder as u32) * 256 + digit as u32;
291            remainder = (value % 62) as u8;
292            quotient.push((value / 62) as u8);
293        }
294        // remove leading zeros
295        while quotient.len() > 1 && quotient[0] == 0 {
296            quotient.remove(0);
297        }
298        (quotient, remainder)
299    }
300    /// Encodes the input bytes into a Base62 string.
301    pub fn encode(input: &[u8]) -> String {
302        let zeros = input.iter().take_while(|&&x| x == 0).count();
303
304        let mut num = input.to_vec();
305        let mut encoded = String::new();
306
307        while !num.iter().all(|&x| x == 0) {
308            let (quotient, remainder) = Self::divmod62(&num);
309            encoded.push_str(BASE62_MAP[remainder as usize]);
310            num = quotient;
311        }
312
313        for _ in 0..zeros {
314            encoded.push('1');
315        }
316
317        encoded = encoded.chars().rev().collect();
318        encoded
319    }
320    /// Decodes a Base62 string into a Vec<u8>.
321    pub fn decode(input: &str) -> Vec<u8> {
322        let mut num = vec![0u8];
323        for c in input.chars() {
324            let val = BASE62_REVERSE_MAP[c as usize];
325            if val == 255 {
326                // invalid character, skip it
327                continue;
328            }
329            let mut carry = val as u32;
330            for n in num.iter_mut() {
331                let total = *n as u32 * 62 + carry;
332                *n = (total & 0xff) as u8;
333                carry = total >> 8;
334            }
335
336            while carry > 0 {
337                num.push((carry & 0xff) as u8);
338                carry >>= 8;
339            }
340        }
341
342        let mut n_zeros = 0;
343        for c in input.chars() {
344            if c == '0' {
345                n_zeros += 1;
346            } else {
347                break;
348            }
349        }
350        let mut result = vec![0u8; n_zeros];
351        result.extend(num.iter().rev());
352        result
353    }
354}
355
356const BASE64_MAP: [&str; 64] = [
357    "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
358    "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
359    "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4",
360    "5", "6", "7", "8", "9", "+", "/",
361];
362
363const BASE64_REVERSE_MAP: [u8; 256] = [
364    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
365    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
366    255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255,
367    255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
368    19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34,
369    35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
370    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
371    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
372    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
373    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
374    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
375    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
376    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
377];
378pub struct Base64;
379
380impl Base64 {
381    /// Encodes the input bytes into a Base64 string.
382    /// ```rust
383    /// use codeckit::Base64;
384    ///
385    /// fn main() {
386    ///     let test_str = "test";
387    ///     let encoded = Base64::encode(test_str.as_bytes());
388    ///     println!("{}", encoded);
389    ///     let original = Base64::decode(&encoded);
390    ///     let original = String::from_utf8(original).unwrap();
391    ///     println!("{:?}", original);
392    /// }
393    /// ```
394    pub fn encode(input: &[u8]) -> String {
395        let mut ret = String::with_capacity(((input.len() + 2) / 3) * 4);
396        let mut flag = 0;
397        let mut prev: u8 = 0;
398
399        for &i in input {
400            match flag {
401                0 => {
402                    let ind = i >> 2;
403                    prev = (i & 0b00000011) << 4;
404                    ret.push_str(BASE64_MAP[ind as usize]);
405                    flag = 1;
406                }
407                1 => {
408                    let ind = prev + (i >> 4);
409                    prev = (i & 0b00001111) << 2;
410                    ret.push_str(BASE64_MAP[ind as usize]);
411                    flag = 2;
412                }
413                2 => {
414                    let ind = prev + (i >> 6);
415                    let ind_1 = i & 0b00111111;
416                    ret.push_str(BASE64_MAP[ind as usize]);
417                    ret.push_str(BASE64_MAP[ind_1 as usize]);
418                    prev = 0;
419                    flag = 0;
420                }
421                _ => unreachable!(),
422            }
423        }
424
425        ret.push_str(BASE64_MAP[prev as usize]);
426        // add padding if necessary
427        while ret.len() % 4 != 0 {
428            ret.push('=');
429        }
430        ret
431    }
432    /// Decodes a Base64 string into a Vec<u8>.
433    /// This function ignores invalid characters automatically and not returns an error.
434    pub fn decode(input: &str) -> Vec<u8> {
435        let mut ret: Vec<u8> = Vec::with_capacity((input.len() / 4) * 3);
436        let mut flag: u8 = 0;
437        let mut prev: u8 = 0;
438        for i in input.chars() {
439            if i == '=' {
440                break;
441            }
442            let i_rev = BASE64_REVERSE_MAP[i as usize];
443            // drop invalid characters and 255 means invalid character
444            if i_rev == 255 {
445                continue;
446            }
447            match flag {
448                0 => {
449                    prev = i_rev << 2;
450                    flag = 1;
451                }
452                1 => {
453                    let ch = prev + ((i_rev & 0b00110000) >> 4);
454                    if ch != 0 {
455                        ret.push(ch);
456                    }
457                    prev = (i_rev & 0b00001111) << 4;
458                    flag = 2;
459                }
460                2 => {
461                    let ch = prev + ((i_rev & 0b00111100) >> 2);
462                    if ch != 0 {
463                        ret.push(ch);
464                    }
465                    prev = (i_rev & 0b00000011) << 6;
466                    flag = 3;
467                }
468                3 => {
469                    let ch = prev + (i_rev & 0b00111111);
470                    if ch != 0 {
471                        ret.push(ch);
472                    }
473                    prev = 0;
474                    flag = 0;
475                }
476                _ => unreachable!(),
477            }
478        }
479        match flag {
480            1 | 2 | 3 => {
481                if prev != 0 {
482                    ret.push(prev);
483                }
484            }
485            _ => (), // ignore 0
486        }
487        ret
488    }
489}
490
491const BASE64_URL_MAP: [&str; 64] = [
492    "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S",
493    "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
494    "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4",
495    "5", "6", "7", "8", "9", "-", "_",
496];
497
498const BASE64_URL_REVERSE_MAP: [u8; 256] = [
499    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
500    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
501    255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255,
502    255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
503    19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 63, 255, 26, 27, 28, 29, 30, 31, 32, 33, 34,
504    35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
505    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
506    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
507    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
508    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
509    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
510    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
511    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
512];
513
514pub struct Base64Url;
515
516impl Base64Url {
517    /// Encodes the input bytes into a Base64Url string.
518    /// If padding is true, it will add '=' padding characters to the end of the string.
519    pub fn encode(input: &[u8], padding: bool) -> String {
520        let mut ret = String::with_capacity(((input.len() + 2) / 3) * 4);
521        let mut flag = 0;
522        let mut prev: u8 = 0;
523
524        for &i in input {
525            match flag {
526                0 => {
527                    let ind = i >> 2;
528                    prev = (i & 0b00000011) << 4;
529                    ret.push_str(BASE64_URL_MAP[ind as usize]);
530                    flag = 1;
531                }
532                1 => {
533                    let ind = prev + (i >> 4);
534                    prev = (i & 0b00001111) << 2;
535                    ret.push_str(BASE64_URL_MAP[ind as usize]);
536                    flag = 2;
537                }
538                2 => {
539                    let ind = prev + (i >> 6);
540                    let ind_1 = i & 0b00111111;
541                    ret.push_str(BASE64_URL_MAP[ind as usize]);
542                    ret.push_str(BASE64_URL_MAP[ind_1 as usize]);
543                    prev = 0;
544                    flag = 0;
545                }
546                _ => unreachable!(),
547            }
548        }
549
550        ret.push_str(BASE64_URL_MAP[prev as usize]);
551        if padding {
552            // add padding if necessary
553            while ret.len() % 4 != 0 {
554                ret.push('=');
555            }
556        }
557        ret
558    }
559    /// Decodes a Base64Url string into a Vec<u8>.
560    pub fn decode(input: &str) -> Vec<u8> {
561        let mut ret: Vec<u8> = Vec::with_capacity((input.len() / 4) * 3);
562        let mut flag: u8 = 0;
563        let mut prev: u8 = 0;
564        for i in input.chars() {
565            if i == '=' {
566                break;
567            }
568            let i_rev = BASE64_URL_REVERSE_MAP[i as usize];
569            // drop invalid characters and 255 means invalid character
570            if i_rev == 255 {
571                continue;
572            }
573            match flag {
574                0 => {
575                    prev = i_rev << 2;
576                    flag = 1;
577                }
578                1 => {
579                    let ch = prev + ((i_rev & 0b00110000) >> 4);
580                    if ch != 0 {
581                        ret.push(ch);
582                    }
583                    prev = (i_rev & 0b00001111) << 4;
584                    flag = 2;
585                }
586                2 => {
587                    let ch = prev + ((i_rev & 0b00111100) >> 2);
588                    if ch != 0 {
589                        ret.push(ch);
590                    }
591                    prev = (i_rev & 0b00000011) << 6;
592                    flag = 3;
593                }
594                3 => {
595                    let ch = prev + (i_rev & 0b00111111);
596                    if ch != 0 {
597                        ret.push(ch);
598                    }
599                    prev = 0;
600                    flag = 0;
601                }
602                _ => unreachable!(),
603            }
604        }
605        match flag {
606            1 | 2 | 3 => {
607                if prev != 0 {
608                    ret.push(prev);
609                }
610            }
611            _ => (), // ignore 0
612        }
613        ret
614    }
615}
616
617pub struct Ascii85;
618
619impl Ascii85 {
620    fn divmod85(num: &[u8]) -> (Vec<u8>, u8) {
621        let mut quotient = Vec::new();
622        let mut remainder: u8 = 0;
623        for &digit in num {
624            let value = (remainder as u32) * 256 + digit as u32;
625            remainder = (value % 85) as u8;
626            quotient.push((value / 85) as u8);
627        }
628        // remove leading zeros
629        while quotient.len() > 1 && quotient[0] == 0 {
630            quotient.remove(0);
631        }
632        (quotient, remainder)
633    }
634    /// Encodes a 4-byte chunk into a Ascii85 string.
635    /// This function is used internally by the `encode` method.
636    fn inner_encode(input: &[u8]) -> String {
637        if input.iter().all(|&x| x == 0) {
638            return "z".to_string(); // special case for all zeros
639        } else {
640            let mut encoded = String::new();
641            let mut num = input.to_vec();
642
643            while !num.iter().all(|&x| x == 0) {
644                let (quotient, remainder) = Self::divmod85(&num);
645                let remainder_char = (remainder + 33) as char;
646                encoded.push(remainder_char);
647                num = quotient;
648            }
649            encoded.chars().rev().collect()
650        }
651    }
652    /// Encodes the input bytes into a Base85 string.
653    pub fn encode(input: &[u8]) -> String {
654        let mut num = input.to_vec();
655        let mut padding: u8 = 0;
656        while num.len() % 4 != 0 {
657            num.push(0); // pad with zeros to make the length a multiple of 4
658            padding += 1;
659        }
660
661        let ind = num.len() / 4;
662        let mut ret = Vec::new();
663        for i in 0..ind {
664            let start = i * 4;
665            let end = start + 4;
666            let chunk = &num[start..end];
667            let encoded_chunk = Self::inner_encode(chunk);
668
669            let encoded_chunk = if i == ind - 1 {
670                let encoded_chunk = match padding {
671                    0 => encoded_chunk,                   // no padding
672                    1 => encoded_chunk[0..4].to_string(), // keep first 4 chars
673                    2 => encoded_chunk[0..3].to_string(), // keep first 3 chars
674                    3 => encoded_chunk[0..2].to_string(), // keep first 2 chars
675                    _ => unreachable!(),                  // should never happen
676                };
677                encoded_chunk
678            } else {
679                encoded_chunk
680            };
681            ret.push(encoded_chunk);
682        }
683        ret.join("")
684    }
685    /// Decodes 5 characters of Base85 into a Vec<u8>.
686    /// This function is used internally by the `decode` method.
687    fn inner_decode(input_chars: &[u8]) -> Vec<u8> {
688        let mut num: Vec<u8> = vec![0];
689        for &c in input_chars {
690            if c > 84 {
691                // invalid character, skip it
692                continue;
693            }
694            if c + 33 == ('z' as u8) {
695                // special case for all zeros
696                num.extend(vec![0, 0, 0, 0]);
697            } else {
698                let mut carry = c as u32;
699                for n in num.iter_mut() {
700                    let total = *n as u32 * 85 + carry;
701                    *n = (total & 0xff) as u8;
702                    carry = total >> 8;
703                }
704
705                while carry > 0 {
706                    num.push((carry & 0xff) as u8);
707                    carry >>= 8;
708                }
709            }
710        }
711        num.reverse();
712        num
713    }
714    /// Decodes a Base85 string into a Vec<u8>.
715    pub fn decode(input: &str) -> Vec<u8> {
716        let mut ret = Vec::new();
717        if input.len() == 0 {
718            return ret; // empty input
719        }
720
721        let mut input_chars: Vec<u8> = input.chars().into_iter().map(|x| x as u8 - 33).collect();
722        let mut padding: u8 = 0;
723        while input_chars.len() % 5 != 0 {
724            input_chars.push(84); // pad with 84 to make the length a multiple of 5
725            padding += 1;
726        }
727
728        let ind = input_chars.len() / 5;
729        for i in 0..ind {
730            let start = i * 5;
731            let end = start + 5;
732            let chunk = &input_chars[start..end];
733            let decoded_chunk = Self::inner_decode(chunk);
734
735            let decoded_chunk = if i == ind - 1 {
736                // remove padding
737                match padding {
738                    0 => decoded_chunk,                // no padding
739                    1 => decoded_chunk[0..3].to_vec(), // keep first 3 bytes
740                    2 => decoded_chunk[0..2].to_vec(), // keep first 2 bytes
741                    3 => decoded_chunk[0..1].to_vec(), // keep first 1 bytes
742                    _ => unreachable!(),               // should never happen
743                }
744            } else {
745                decoded_chunk
746            };
747            ret.extend(decoded_chunk);
748        }
749        ret
750    }
751}
752
753const BASE85_GIT_MAP: [&str; 85] = [
754    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
755    "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b",
756    "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u",
757    "v", "w", "x", "y", "z", "!", "#", "$", "%", "&", "(", ")", "*", "+", "-", ";", "<", "=", ">",
758    "?", "@", "^", "_", "`", "{", "|", "}", "~",
759];
760
761const BASE85_GIT_REVERSE_MAP: [u8; 256] = [
762    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
763    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 63, 64, 65, 66,
764    255, 67, 68, 69, 70, 255, 71, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 72, 73, 74, 75, 76,
765    77, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
766    33, 34, 35, 255, 255, 255, 78, 79, 80, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
767    50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 81, 82, 83, 84, 255, 255, 255, 255, 255, 255,
768    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
769    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
770    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
771    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
772    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
773    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
774    255, 255, 255, 255, 255, 255, 255, 255, 255,
775];
776
777pub struct Base85Git;
778
779impl Base85Git {
780    fn divmod85(num: &[u8]) -> (Vec<u8>, u8) {
781        let mut quotient = Vec::new();
782        let mut remainder: u8 = 0;
783        for &digit in num {
784            let value = (remainder as u32) * 256 + digit as u32;
785            remainder = (value % 85) as u8;
786            quotient.push((value / 85) as u8);
787        }
788        // remove leading zeros
789        while quotient.len() > 1 && quotient[0] == 0 {
790            quotient.remove(0);
791        }
792        (quotient, remainder)
793    }
794    /// Encodes a 4-byte chunk into a Base85Git string.
795    /// This function is used internally by the `encode` method.
796    fn inner_encode(input: &[u8]) -> String {
797        let mut encoded = String::new();
798        let mut num = input.to_vec();
799
800        while !num.iter().all(|&x| x == 0) {
801            let (quotient, remainder) = Self::divmod85(&num);
802            let remainder_char = BASE85_GIT_MAP[remainder as usize];
803            encoded.push_str(remainder_char);
804            num = quotient;
805        }
806        encoded.chars().rev().collect()
807    }
808    /// Encodes the input bytes into a Base85Git string.
809    pub fn encode(input: &[u8]) -> String {
810        let mut num = input.to_vec();
811        let mut padding: u8 = 0;
812        while num.len() % 4 != 0 {
813            num.push(0); // pad with zeros to make the length a multiple of 4
814            padding += 1;
815        }
816
817        let ind = num.len() / 4;
818        let mut ret = Vec::new();
819        for i in 0..ind {
820            let start = i * 4;
821            let end = start + 4;
822            let chunk = &num[start..end];
823            let encoded_chunk = Self::inner_encode(chunk);
824
825            let encoded_chunk = if i == ind - 1 {
826                match padding {
827                    0 => encoded_chunk,                   // no padding
828                    1 => encoded_chunk[0..4].to_string(), // keep first 4 chars
829                    2 => encoded_chunk[0..3].to_string(), // keep first 3 chars
830                    3 => encoded_chunk[0..2].to_string(), // keep first 2 chars
831                    _ => unreachable!(),                  // should never happen
832                }
833            } else {
834                encoded_chunk
835            };
836            ret.push(encoded_chunk);
837        }
838        ret.join("")
839    }
840    /// Decodes 5 characters of Base85Git into a Vec<u8>.
841    /// This function is used internally by the `decode` method.
842    fn inner_decode(input_chars: &[u8]) -> Vec<u8> {
843        let mut num: Vec<u8> = vec![0];
844        for &c in input_chars {
845            if c > 84 {
846                // invalid character, skip it
847                continue;
848            }
849            let mut carry = c as u32;
850            for n in num.iter_mut() {
851                let total = *n as u32 * 85 + carry;
852                *n = (total & 0xff) as u8;
853                carry = total >> 8;
854            }
855
856            while carry > 0 {
857                num.push((carry & 0xff) as u8);
858                carry >>= 8;
859            }
860        }
861        num.reverse();
862        num
863    }
864    /// Decodes a Base85Git string into a Vec<u8>.
865    pub fn decode(input: &str) -> Vec<u8> {
866        let mut ret = Vec::new();
867        if input.len() == 0 {
868            return ret; // empty input
869        }
870
871        let mut input_chars: Vec<u8> = input
872            .chars()
873            .into_iter()
874            .map(|x| BASE85_GIT_REVERSE_MAP[x as usize])
875            .collect();
876        let mut padding: u8 = 0;
877        while input_chars.len() % 5 != 0 {
878            input_chars.push(84); // pad with 84 to make the length a multiple of 5
879            padding += 1;
880        }
881
882        let ind = input_chars.len() / 5;
883        for i in 0..ind {
884            let start = i * 5;
885            let end = start + 5;
886            let chunk = &input_chars[start..end];
887            let decoded_chunk = Self::inner_decode(chunk);
888
889            let decoded_chunk = if i == ind - 1 {
890                // remove padding
891                match padding {
892                    0 => decoded_chunk,                // no padding
893                    1 => decoded_chunk[0..3].to_vec(), // keep first 3 bytes
894                    2 => decoded_chunk[0..2].to_vec(), // keep first 2 bytes
895                    3 => decoded_chunk[0..1].to_vec(), // keep first 1 bytes
896                    _ => unreachable!(),               // should never happen
897                }
898            } else {
899                decoded_chunk
900            };
901            ret.extend(decoded_chunk);
902        }
903        ret
904    }
905}
906
907const Z85_MAP: [&str; 85] = [
908    "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "g", "h", "i",
909    "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "A", "B",
910    "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U",
911    "V", "W", "X", "Y", "Z", ".", "-", ":", "+", "=", "^", "!", "/", "*", "?", "&", "<", ">", "(",
912    ")", "[", "]", "{", "}", "@", "%", "$", "#",
913];
914
915const Z85_REVERSE_MAP: [u8; 256] = [
916    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
917    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 68, 255, 84, 83, 82, 72,
918    255, 75, 76, 70, 65, 255, 63, 62, 69, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 64, 255, 73, 66, 74, 71,
919    81, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
920    59, 60, 61, 77, 255, 78, 67, 255, 255, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
921    24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 79, 255, 80, 255, 255, 255, 255, 255, 255, 255,
922    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
923    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
924    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
925    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
926    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
927    255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
928    255, 255, 255, 255, 255, 255, 255, 255, 255,
929];
930
931pub struct Z85;
932
933impl Z85 {
934    fn divmod85(num: &[u8]) -> (Vec<u8>, u8) {
935        let mut quotient = Vec::new();
936        let mut remainder: u8 = 0;
937        for &digit in num {
938            let value = (remainder as u32) * 256 + digit as u32;
939            remainder = (value % 85) as u8;
940            quotient.push((value / 85) as u8);
941        }
942        // remove leading zeros
943        while quotient.len() > 1 && quotient[0] == 0 {
944            quotient.remove(0);
945        }
946        (quotient, remainder)
947    }
948    /// Encodes a 4-byte chunk into a Z85 string.
949    /// This function is used internally by the `encode` method.
950    fn inner_encode(input: &[u8]) -> String {
951        let mut encoded = String::new();
952        let mut num = input.to_vec();
953
954        while !num.iter().all(|&x| x == 0) {
955            let (quotient, remainder) = Self::divmod85(&num);
956            let remainder_char = Z85_MAP[remainder as usize];
957            encoded.push_str(remainder_char);
958            num = quotient;
959        }
960        encoded.chars().rev().collect()
961    }
962    /// Encodes the input bytes into a Z85 string.
963    pub fn encode(input: &[u8]) -> String {
964        let mut num = input.to_vec();
965        let mut padding: u8 = 0;
966        while num.len() % 4 != 0 {
967            num.push(0); // pad with zeros to make the length a multiple of 4
968            padding += 1;
969        }
970
971        let ind = num.len() / 4;
972        let mut ret = Vec::new();
973        for i in 0..ind {
974            let start = i * 4;
975            let end = start + 4;
976            let chunk = &num[start..end];
977            let encoded_chunk = Self::inner_encode(chunk);
978
979            let encoded_chunk = if i == ind - 1 {
980                match padding {
981                    0 => encoded_chunk,                   // no padding
982                    1 => encoded_chunk[0..4].to_string(), // keep first 4 chars
983                    2 => encoded_chunk[0..3].to_string(), // keep first 3 chars
984                    3 => encoded_chunk[0..2].to_string(), // keep first 2 chars
985                    _ => unreachable!(),                  // should never happen
986                }
987            } else {
988                encoded_chunk
989            };
990            ret.push(encoded_chunk);
991        }
992        ret.join("")
993    }
994    /// Decodes 5 characters of Z85 into a Vec<u8>.
995    /// This function is used internally by the `decode` method.
996    fn inner_decode(input_chars: &[u8]) -> Vec<u8> {
997        let mut num: Vec<u8> = vec![0];
998        for &c in input_chars {
999            if c > 84 {
1000                // invalid character, skip it
1001                continue;
1002            }
1003            let mut carry = c as u32;
1004            for n in num.iter_mut() {
1005                let total = *n as u32 * 85 + carry;
1006                *n = (total & 0xff) as u8;
1007                carry = total >> 8;
1008            }
1009
1010            while carry > 0 {
1011                num.push((carry & 0xff) as u8);
1012                carry >>= 8;
1013            }
1014        }
1015        num.reverse();
1016        num
1017    }
1018    /// Decodes a Z85 string into a Vec<u8>.
1019    pub fn decode(input: &str) -> Vec<u8> {
1020        let mut ret = Vec::new();
1021        if input.len() == 0 {
1022            return ret; // empty input
1023        }
1024
1025        let mut input_chars: Vec<u8> = input
1026            .chars()
1027            .into_iter()
1028            .map(|x| Z85_REVERSE_MAP[x as usize])
1029            .collect();
1030        let mut padding: u8 = 0;
1031        while input_chars.len() % 5 != 0 {
1032            input_chars.push(84); // pad with 84 to make the length a multiple of 5
1033            padding += 1;
1034        }
1035
1036        let ind = input_chars.len() / 5;
1037        for i in 0..ind {
1038            let start = i * 5;
1039            let end = start + 5;
1040            let chunk = &input_chars[start..end];
1041            let decoded_chunk = Self::inner_decode(chunk);
1042
1043            let decoded_chunk = if i == ind - 1 {
1044                // remove padding
1045                match padding {
1046                    0 => decoded_chunk,                // no padding
1047                    1 => decoded_chunk[0..3].to_vec(), // keep first 3 bytes
1048                    2 => decoded_chunk[0..2].to_vec(), // keep first 2 bytes
1049                    3 => decoded_chunk[0..1].to_vec(), // keep first 1 bytes
1050                    _ => unreachable!(),               // should never happen
1051                }
1052            } else {
1053                decoded_chunk
1054            };
1055            ret.extend(decoded_chunk);
1056        }
1057        ret
1058    }
1059}
1060
1061#[cfg(test)]
1062mod tests {
1063    use super::*;
1064    #[test]
1065    fn test_z85() {
1066        let test = "hello";
1067        // let test = "test";
1068        println!("{:?}", test.as_bytes());
1069        let output = Z85::encode(test.as_bytes());
1070        println!("{}", output);
1071        let output = Z85::decode(&output);
1072        println!("{:?}", output);
1073        let output = String::from_utf8(output).unwrap();
1074        println!("{:?}", output);
1075
1076        let test = "testz00";
1077        println!("{:?}", test.as_bytes());
1078        let output = Z85::encode(test.as_bytes());
1079        println!("{}", output);
1080        let output = Z85::decode(&output);
1081        println!("{:?}", output);
1082        let output = String::from_utf8(output).unwrap();
1083        println!("{:?}", output);
1084
1085        let test = "中文测试";
1086        println!("{:?}", test.as_bytes());
1087        let output = Z85::encode(test.as_bytes());
1088        println!("{}", output);
1089        let output = Z85::decode(&output);
1090        println!("{:?}", output);
1091        let output = String::from_utf8(output).unwrap();
1092        println!("{:?}", output);
1093    }
1094    #[test]
1095    fn test_base85_git() {
1096        let test = "hello";
1097        // println!("{:?}", test.as_bytes());
1098        let output = Base85Git::encode(test.as_bytes());
1099        println!("{}", output);
1100        let output = Base85Git::decode(&output);
1101        let output = String::from_utf8(output).unwrap();
1102        println!("{:?}", output);
1103
1104        let test = "中文测试";
1105        // println!("{:?}", test.as_bytes());
1106        let output = Base85Git::encode(test.as_bytes());
1107        println!("{}", output);
1108        let output = Base85Git::decode(&output);
1109        let output = String::from_utf8(output).unwrap();
1110        println!("{:?}", output);
1111    }
1112    #[test]
1113    fn test_ascii85() {
1114        let test = "hello";
1115        // let test = "test";
1116        println!("{:?}", test.as_bytes());
1117        let output = Ascii85::encode(test.as_bytes());
1118        println!("{}", output);
1119        let output = Ascii85::decode(&output);
1120        println!("{:?}", output);
1121        let output = String::from_utf8(output).unwrap();
1122        println!("{:?}", output);
1123
1124        let test = "testz00";
1125        println!("{:?}", test.as_bytes());
1126        let output = Ascii85::encode(test.as_bytes());
1127        println!("{}", output);
1128        let output = Ascii85::decode(&output);
1129        println!("{:?}", output);
1130        let output = String::from_utf8(output).unwrap();
1131        println!("{:?}", output);
1132
1133        let test = "中文测试";
1134        println!("{:?}", test.as_bytes());
1135        let output = Ascii85::encode(test.as_bytes());
1136        println!("{}", output);
1137        let output = Ascii85::decode(&output);
1138        println!("{:?}", output);
1139        let output = String::from_utf8(output).unwrap();
1140        println!("{:?}", output);
1141    }
1142    #[test]
1143    fn test_base64_url() {
1144        let test = "test";
1145        let output = Base64Url::encode(test.as_bytes(), false);
1146        println!("{}", output);
1147        let output = Base64Url::decode(&output);
1148        let output = String::from_utf8(output).unwrap();
1149        println!("{:?}", output);
1150
1151        let test = "fasdfa";
1152        // println!("{:?}", test.as_bytes());
1153        let output = Base64Url::encode(test.as_bytes(), false);
1154        println!("{}", output);
1155        let output = Base64Url::decode(&output);
1156        let output = String::from_utf8(output).unwrap();
1157        println!("{:?}", output);
1158
1159        let test = "中文测试";
1160        // println!("{:?}", test.as_bytes());
1161        let output = Base64Url::encode(test.as_bytes(), false);
1162        println!("{}", output);
1163        let output = Base64Url::decode(&output);
1164        let output = String::from_utf8(output).unwrap();
1165        println!("{:?}", output);
1166    }
1167    #[test]
1168    fn test_base62() {
1169        let test = "test";
1170        let output = Base62::encode(test.as_bytes());
1171        println!("{}", output);
1172        let output = Base62::decode(&output);
1173        let output = String::from_utf8(output).unwrap();
1174        println!("{:?}", output);
1175
1176        let test = "fasdfa";
1177        // println!("{:?}", test.as_bytes());
1178        let output = Base62::encode(test.as_bytes());
1179        println!("{}", output);
1180        let output = Base62::decode(&output);
1181        let output = String::from_utf8(output).unwrap();
1182        println!("{:?}", output);
1183
1184        let test = "中文测试";
1185        // println!("{:?}", test.as_bytes());
1186        let output = Base62::encode(test.as_bytes());
1187        println!("{}", output);
1188        let output = Base62::decode(&output);
1189        let output = String::from_utf8(output).unwrap();
1190        println!("{:?}", output);
1191    }
1192    #[test]
1193    fn test_base58() {
1194        let test = "test";
1195        let output = Base58::encode(test.as_bytes());
1196        println!("{}", output);
1197        let output = Base58::decode(&output);
1198        let output = String::from_utf8(output).unwrap();
1199        println!("{:?}", output);
1200
1201        let test = "fasdfa";
1202        // println!("{:?}", test.as_bytes());
1203        let output = Base58::encode(test.as_bytes());
1204        println!("{}", output);
1205        let output = Base58::decode(&output);
1206        let output = String::from_utf8(output).unwrap();
1207        println!("{:?}", output);
1208
1209        let test = "中文测试";
1210        // println!("{:?}", test.as_bytes());
1211        let output = Base58::encode(test.as_bytes());
1212        println!("{}", output);
1213        let output = Base58::decode(&output);
1214        let output = String::from_utf8(output).unwrap();
1215        println!("{:?}", output);
1216    }
1217    #[test]
1218    fn test_base32() {
1219        let test = "test";
1220        let output = Base32::encode(test.as_bytes());
1221        println!("{}", output);
1222        let output = Base32::decode(&output);
1223        let output = String::from_utf8(output).unwrap();
1224        println!("{:?}", output);
1225
1226        let test = "fasdfa";
1227        // println!("{:?}", test.as_bytes());
1228        let output = Base32::encode(test.as_bytes());
1229        println!("{}", output);
1230        let output = Base32::decode(&output);
1231        let output = String::from_utf8(output).unwrap();
1232        println!("{:?}", output);
1233
1234        let test = "中文测试";
1235        let output = Base32::encode(test.as_bytes());
1236        println!("{}", output);
1237        let output = Base32::decode(&output);
1238        let output = String::from_utf8(output).unwrap();
1239        println!("{:?}", output);
1240    }
1241    #[test]
1242    fn test_base64() {
1243        let test = "test";
1244        let output = Base64::encode(test.as_bytes());
1245        println!("{}", output);
1246        let output = Base64::decode(&output);
1247        let output = String::from_utf8(output).unwrap();
1248        println!("{:?}", output);
1249
1250        let test = "fasdfa";
1251        let output = Base64::encode(test.as_bytes());
1252        println!("{}", output);
1253        let output = Base64::decode(&output);
1254        let output = String::from_utf8(output).unwrap();
1255        println!("{:?}", output);
1256
1257        let test = "中文测试";
1258        let output = Base64::encode(test.as_bytes());
1259        println!("{}", output);
1260        let output = Base64::decode(&output);
1261        let output = String::from_utf8(output).unwrap();
1262        println!("{:?}", output);
1263    }
1264    #[test]
1265    fn script1() {
1266        // generate the base64 map
1267        let gen_map = |input: &str| {
1268            let mut res = Vec::new();
1269            for b in input.chars() {
1270                let fmt_str = format!("\"{}\"", b);
1271                res.push(fmt_str);
1272            }
1273            let res_str = res.join(", ");
1274            println!("[{}]", res_str);
1275        };
1276
1277        let gen_res_map = |input: &str| {
1278            let mut test: Vec<u8> = vec![255; 256];
1279            for (i, b) in input.chars().into_iter().enumerate() {
1280                let b_u8 = b as u8;
1281                test[b_u8 as usize] = i as u8;
1282            }
1283            println!("{:?}", test);
1284        };
1285
1286        let base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1287        println!(">>>>>>>>>>>>>>");
1288        gen_map(base64);
1289        println!(">>>>>>>>>>>>>>");
1290        gen_res_map(base64);
1291
1292        let base32 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
1293        println!(">>>>>>>>>>>>>>");
1294        gen_map(base32);
1295        println!(">>>>>>>>>>>>>>");
1296        gen_res_map(base32);
1297
1298        let base58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
1299        println!(">>>>>>>>>>>>>>");
1300        gen_map(base58);
1301        println!(">>>>>>>>>>>>>>");
1302        gen_res_map(base58);
1303
1304        let base62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
1305        println!(">>>>>>>>>>>>>>");
1306        gen_map(base62);
1307        println!(">>>>>>>>>>>>>>");
1308        gen_res_map(base62);
1309
1310        let base64url = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
1311        println!(">>>>>>>>>>>>>>");
1312        gen_map(base64url);
1313        println!(">>>>>>>>>>>>>>");
1314        gen_res_map(base64url);
1315
1316        let base85git =
1317            "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~";
1318        println!(">>>>>>>>>>>>>>");
1319        gen_map(base85git);
1320        println!(">>>>>>>>>>>>>>");
1321        gen_res_map(base85git);
1322
1323        let chars = base85git.chars().collect::<Vec<char>>();
1324        let w85 = chars[82];
1325        println!("w85: {}", w85);
1326        let w55 = chars[55];
1327        println!("w55: {}", w55);
1328
1329        let z85 =
1330            "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-:+=^!/*?&<>()[]{}@%$#";
1331        println!(">>>>>>>>>>>>>>");
1332        gen_map(z85);
1333        println!(">>>>>>>>>>>>>>");
1334        gen_res_map(z85);
1335
1336        let base91 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~\"";
1337        println!(">>>>>>>>>>>>>>");
1338        gen_map(base91);
1339        println!(">>>>>>>>>>>>>>");
1340        gen_res_map(base91);
1341    }
1342    #[test]
1343    fn shift() {
1344        let x: u8 = 0b00001111;
1345        let y: u8 = x << 2;
1346        println!("{}", y);
1347    }
1348}