Broken b64 implementation (Ugly and no padding)
parent
959093c408
commit
f8a7c5527a
|
@ -5,7 +5,20 @@
|
|||
////
|
||||
|
||||
use std::env;
|
||||
use std::convert::TryInto;
|
||||
|
||||
static BASE64_TABLE: &'static [char] = &['A','B','C','D','E','F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V' ,'W' ,'X' ,'Y' ,'Z',
|
||||
'a','b','c','d','e','f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v' ,'w' ,'x' ,'y' ,'z',
|
||||
'0','1','2','3','4','5', '6', '7', '8', '9', '+', '/'];
|
||||
|
||||
/// Convert Hex String to char
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ~~~
|
||||
/// hex_to_char("49") => I
|
||||
/// ~~~
|
||||
/// TODO: the name is not accurate. Take a string and convert to u8
|
||||
fn hex_to_char(s: &str) -> Result<char, std::num::ParseIntError> {
|
||||
u8::from_str_radix(s, 16).map(|n| n as char)
|
||||
}
|
||||
|
@ -14,20 +27,66 @@ fn main() {
|
|||
let args: Vec<String> = env::args().collect();
|
||||
let input = &args[1];
|
||||
|
||||
let mut input_str = String::new();
|
||||
|
||||
let char_vec: Vec<char> = input.chars().collect();
|
||||
let split = &char_vec.chunks(2)
|
||||
let hex_char = &char_vec
|
||||
.chunks(2)
|
||||
.map(|chunk| chunk.iter().collect::<String>())
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Printing the string in Ascii format - for decoding example
|
||||
for (i, s) in split.iter().enumerate() {
|
||||
print!("Input string in ASCII is : « ");
|
||||
for (i, s) in hex_char.into_iter().enumerate() {
|
||||
match hex_to_char(s) {
|
||||
Ok(s) => print!("{}", s),
|
||||
Ok(s) => input_str.push(s),
|
||||
Err(e) => println!("\nError decoding char '{}' at index {}", e, i),
|
||||
}
|
||||
}
|
||||
println!();
|
||||
println!(" »");
|
||||
|
||||
// Now we can unroll the base64 algorithm
|
||||
// We need to : http://www.herongyang.com/Encoding/Base64-Encoding-Algorithm.html
|
||||
// Convert hex_char : Vec<String> into Vec<u8>
|
||||
// Warning: Panic if not base16
|
||||
// See this with .map_err if we need to improve :
|
||||
// https://play.rust-lang.org/?version=stable&mode=debug&edition=2015&gist=e241493d100ecaadac3c99f37d0f766f
|
||||
let hex: Vec<u8> = hex_char
|
||||
.into_iter()
|
||||
.map(|i| u8::from_str_radix(i, 16).unwrap())
|
||||
.collect();
|
||||
|
||||
println!(" Len is : {}, is it modulo 3-bytes ? {}",
|
||||
&hex.len(),
|
||||
if &hex.len()%3 == 0 { "true" } else { "false"}
|
||||
);
|
||||
|
||||
print!("b64_encode({:?}) ==> ", &input_str);
|
||||
|
||||
// Ugly right ?
|
||||
for j in (0..hex.len()).step_by(3) {
|
||||
let mut arr = [0u8;4];
|
||||
|
||||
// Must handle Padding here !
|
||||
// Index will be out of bound
|
||||
// Find a way in rust to detect that ? or just compute here.
|
||||
// Si padding 1 = '=' + arr[3] = 0
|
||||
// Si padding 2 = '==' + arr[3] & arr[4] = 0
|
||||
arr[0] = 0;
|
||||
for i in 0..3 {
|
||||
arr[i+1] = hex[i+j];
|
||||
}
|
||||
let tmp = u32::from_be_bytes(arr);
|
||||
let tmp1:usize = ((tmp>>18) & 0x3F).try_into().unwrap();
|
||||
let tmp2:usize = ((tmp>>12) & 0x3F).try_into().unwrap();
|
||||
|
||||
// If this fail we need to PAD '=='
|
||||
let tmp3:usize = ((tmp>>6) & 0x3F).try_into().unwrap();
|
||||
// If this fail we need to PAD '='
|
||||
let tmp4:usize = ((tmp) & 0x3F).try_into().unwrap();
|
||||
|
||||
print!("{}", BASE64_TABLE[tmp1]);
|
||||
print!("{}", BASE64_TABLE[tmp2]);
|
||||
print!("{}", BASE64_TABLE[tmp3]);
|
||||
print!("{}", BASE64_TABLE[tmp4]);
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue