br_crypto/
base64.rs

1use base64::Engine;
2use base64::engine::general_purpose::{STANDARD};
3use log::{error, info};
4use crate::encoding::code_to_utf8;
5
6/// 加密-Base64URL
7pub fn encode(string: String) -> String {
8    STANDARD.encode(string)
9}
10
11/// 文件加密
12pub fn encode_u8(data: Vec<u8>) -> String {
13    STANDARD.encode(data)
14}
15/// 文件加密
16pub fn encode_file(string: Vec<u8>) -> String {
17    STANDARD.encode(string)
18}
19
20/// 加密-Base64URL
21pub fn url_encode(string: String) -> String {
22    STANDARD.encode(string)
23}
24
25
26/// 解码
27pub fn decode_u8<T: AsRef<[u8]>>(base64: T) -> Vec<u8> {
28    let tt = base64.as_ref().to_vec();
29    _decode_u8(tt).unwrap_or_default()
30}
31
32fn _decode_u8(input: Vec<u8>) -> Result<Vec<u8>, String> {
33    // Base64 字符集
34    let base64_chars = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
35    // 创建一个输出缓冲区
36    let mut output = Vec::new();
37    let mut buffer = [0u8; 4];
38    let mut buffer_len = 0;
39
40    // 迭代输入字符串的字节
41    for byte in input {
42        if byte == b'=' {
43            // 如果遇到填充字符,不增加 buffer_len,因为填充不需要转换
44            break;
45        } else if let Some(pos) = base64_chars.iter().position(|&b| b == byte) {
46            // 将 Base64 字符转换为其对应的 6 位值
47            buffer[buffer_len] = pos as u8;
48            buffer_len += 1;
49        } else {
50            // 如果字符不在 Base64 字符集内,返回错误
51            return Err(format!("Invalid Base64 character: {}", byte as char));
52        }
53        // 当缓冲区满时,解码为字节
54        if buffer_len == 4 {
55            output.push((buffer[0] << 2) | (buffer[1] >> 4));
56            output.push((buffer[1] << 4) | (buffer[2] >> 2));
57            output.push((buffer[2] << 6) | buffer[3]);
58            buffer_len = 0;
59        }
60    }
61
62    // 处理剩余部分,不足4个字符的情况
63    if buffer_len > 1 {
64        output.push((buffer[0] << 2) | (buffer[1] >> 4));
65    }
66    if buffer_len > 2 {
67        output.push((buffer[1] << 4) | (buffer[2] >> 2));
68    }
69
70    Ok(output)
71}
72
73
74/// 解密
75pub fn decode<T: AsRef<[u8]> + std::fmt::Display + Copy>(base64: T) -> String {
76    match STANDARD.decode(base64) {
77        Ok(e) => {
78            String::from_utf8_lossy(&e).to_string()
79        }
80        Err(e) => {
81            error!("错误1: {e} {base64}");
82            "".to_string()
83        }
84    }
85}
86
87/// 解密指定编码
88pub fn decode_code(base64: String, code: &str) -> String {
89    if base64.is_empty() {
90        return "".to_string();
91    }
92    match STANDARD.decode(base64.clone()) {
93        Ok(e) => {
94            code_to_utf8(code, e)
95        }
96        Err(e) => {
97            info!("错误1: {e} {base64}");
98            match e.to_string().as_str() {
99                "Encoded text cannot have a 6-bit remainder." => {
100                    let res = base64.len() % 4;
101                    if res == 0 {
102                        return base64;
103                    }
104                    let len = base64.len();
105                    let txt = &base64.as_str()[(len - res)..len];
106                    let temp = format!("{:=<width$}", "", width = res);
107                    if txt.eq(&temp) {
108                        let f_txt = &base64.as_str()[0..(len - res)];
109                        decode(f_txt).parse().unwrap()
110                    } else {
111                        base64
112                    }
113                }
114                _ => {
115                    base64
116                }
117            }
118        }
119    }
120}
121
122/// url解密
123pub fn url_decode(base64: String) -> String {
124    let base64 = base64.replace("*", "=");
125    let base64 = base64.replace("-", "+");
126    if base64.is_empty() {
127        return "".to_string();
128    }
129    match STANDARD.decode(base64.clone()) {
130        Ok(e) => {
131            let tt = String::from_utf8_lossy(&e);
132            tt.to_string()
133        }
134        Err(e) => {
135            info!("错误2: {e} {base64}");
136            base64
137        }
138    }
139}