use base64::{Engine};
use base64::engine::general_purpose::{STANDARD};
use log::{error, info};
use crate::encoding::code_to_utf8;
pub fn encode(string: String) -> String {
STANDARD.encode(string)
}
pub fn encode_u8(data: Vec<u8>) -> String {
STANDARD.encode(data)
}
pub fn encode_file(string: Vec<u8>) -> String {
STANDARD.encode(string)
}
pub fn url_encode(string: String) -> String {
STANDARD.encode(string)
}
pub fn decode_u8<T: AsRef<[u8]>>(base64: T) -> Vec<u8> {
let tt = base64.as_ref().to_vec();
_decode_u8(tt).unwrap_or_default()
}
fn _decode_u8(input: Vec<u8>) -> Result<Vec<u8>, String> {
let base64_chars = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let mut output = Vec::new();
let mut buffer = [0u8; 4];
let mut buffer_len = 0;
for byte in input {
if byte == b'=' {
break;
} else if let Some(pos) = base64_chars.iter().position(|&b| b == byte) {
buffer[buffer_len] = pos as u8;
buffer_len += 1;
} else {
return Err(format!("Invalid Base64 character: {}", byte as char));
}
if buffer_len == 4 {
output.push((buffer[0] << 2) | (buffer[1] >> 4));
output.push((buffer[1] << 4) | (buffer[2] >> 2));
output.push((buffer[2] << 6) | buffer[3]);
buffer_len = 0;
}
}
if buffer_len > 1 {
output.push((buffer[0] << 2) | (buffer[1] >> 4));
}
if buffer_len > 2 {
output.push((buffer[1] << 4) | (buffer[2] >> 2));
}
Ok(output)
}
pub fn decode<T: AsRef<[u8]> + std::fmt::Display + Copy>(base64: T) -> String {
match STANDARD.decode(base64) {
Ok(e) => {
String::from_utf8_lossy(&e).to_string()
}
Err(e) => {
error!("错误1: {e} {base64}");
"".to_string()
}
}
}
pub fn decode_code(base64: String, code: &str) -> String {
if base64.is_empty() {
return "".to_string();
}
match STANDARD.decode(base64.clone()) {
Ok(e) => {
code_to_utf8(code, e)
}
Err(e) => {
info!("错误1: {e} {base64}");
match e.to_string().as_str() {
"Encoded text cannot have a 6-bit remainder." => {
let res = base64.len() % 4;
if res == 0 {
return base64;
}
let len = base64.len();
let txt = &base64.as_str()[(len - res)..len];
let temp = format!("{:=<width$}", "", width = res);
if txt.eq(&temp) {
let f_txt = &base64.as_str()[0..(len - res)];
decode(f_txt).parse().unwrap()
} else {
base64
}
}
_ => {
base64
}
}
}
}
}
pub fn url_decode(base64: String) -> String {
let base64 = base64.replace("*", "=");
let base64 = base64.replace("-", "+");
if base64.is_empty() {
return "".to_string();
}
match STANDARD.decode(base64.clone()) {
Ok(e) => {
let tt = String::from_utf8_lossy(&e);
tt.to_string()
}
Err(e) => {
info!("错误2: {e} {base64}");
base64
}
}
}