#[macro_export]
macro_rules! base64_decode {
($base64:expr) => {{
const INPUT: &str = $base64;
const BYTES: &[u8] = INPUT.as_bytes();
const LEN: usize = {
let mut index = 0;
let mut start_bit: u8 = 0;
let mut result_idx = 0;
while index < BYTES.len() {
let ascii = BYTES[index];
if ascii == b'=' {
break;
}
if start_bit >= 2 {
result_idx += 1;
}
start_bit = (start_bit + 6) % 8;
index += 1;
}
result_idx
};
const DECODED: [u8; LEN] = {
let mut result = [0u8; LEN];
let mut index = 0;
let mut start_bit: u8 = 0;
let mut byte: u8 = 0;
let mut result_idx = 0;
while index < BYTES.len() && result_idx < LEN {
let ascii = BYTES[index];
if ascii == b'=' {
break;
}
let b64 = if ascii >= b'a' {
26 + ascii - b'a'
} else if ascii >= b'A' {
ascii - b'A'
} else if ascii >= b'0' {
52 + ascii - b'0'
} else if ascii == b'+' {
62
} else if ascii == b'/' {
63
} else {
0xff
};
if start_bit <= 2 {
byte |= b64 << (2 - start_bit);
if start_bit == 2 {
if result_idx < LEN {
result[result_idx] = byte;
result_idx += 1;
}
byte = 0;
}
} else {
byte |= b64 >> (start_bit - 2);
if result_idx < LEN {
result[result_idx] = byte;
result_idx += 1;
}
byte = b64 << (8 - start_bit + 2);
}
start_bit = (start_bit + 6) % 8;
index += 1;
}
result
};
DECODED
}};
}
#[macro_export]
macro_rules! base64_url_unsafe {
($base64:expr) => {{
const INPUT:&[u8] = $base64.as_bytes();
const SUFFIX_LEN:usize = 4 - (INPUT.len() % 4);
const LEN:usize = SUFFIX_LEN + INPUT.len();
const DECODED: [u8; LEN] = {
let mut index = 0;
let mut result = [0u8; LEN];
while index < INPUT.len() {
result[index] = match INPUT[index] {
b'-' => b'+',
b'_' => b'/',
c => c
};
index += 1;
}
let mut index = index;
while index < LEN {
result[index] = b'=';
index += 1;
}
result
};
std::str::from_utf8(&DECODED).unwrap()
}};
}
#[macro_export]
macro_rules! base64_url_safe {
($base64:expr) => {{
const INPUT:&[u8] = $base64.as_bytes();
const SUFFIX_LEN:usize = {
let mut suffix_len:usize = 0;
if INPUT.len() > 0 {
let mut index = INPUT.len() - 1;
while INPUT[index] == b'=' {
suffix_len += 1;
if index == 0 {break}
index -= 1;
}
}
suffix_len
};
const LEN:usize = INPUT.len() - SUFFIX_LEN;
const DECODED: [u8; LEN] = {
let mut index = 0;
let mut result = [0u8; LEN];
while index < LEN {
result[index] = match INPUT[index] {
b'+' => b'-',
b'/' => b'_',
c => c
};
index += 1;
}
result
};
std::str::from_utf8(&DECODED).unwrap()
}};
}