Handle b64 padding if needed

master
Benoît 2020-04-12 23:57:45 +02:00
parent f8a7c5527a
commit 9ec954cd3f
1 changed files with 39 additions and 29 deletions

View File

@ -24,26 +24,23 @@ fn hex_to_char(s: &str) -> Result<char, std::num::ParseIntError> {
} }
fn main() { fn main() {
let mut input_str = String::new();
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
let input = &args[1]; let input = &args[1];
let mut input_str = String::new();
let char_vec: Vec<char> = input.chars().collect(); let char_vec: Vec<char> = input.chars().collect();
let hex_char = &char_vec let hex_char = &char_vec
.chunks(2) .chunks(2)
.map(|chunk| chunk.iter().collect::<String>()) .map(|chunk| chunk.iter().collect::<String>())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
// Printing the string in Ascii format - for decoding example // Printing the string in Ascii format - for hexa to Ascii example
print!("Input string in ASCII is : « ");
for (i, s) in hex_char.into_iter().enumerate() { for (i, s) in hex_char.into_iter().enumerate() {
match hex_to_char(s) { match hex_to_char(s) {
Ok(s) => input_str.push(s), Ok(s) => input_str.push(s),
Err(e) => println!("\nError decoding char '{}' at index {}", e, i), Err(e) => println!("\nError decoding char '{}' at index {}", e, i),
} }
} }
println!(" »");
// Convert hex_char : Vec<String> into Vec<u8> // Convert hex_char : Vec<String> into Vec<u8>
// Warning: Panic if not base16 // Warning: Panic if not base16
@ -54,39 +51,52 @@ fn main() {
.map(|i| u8::from_str_radix(i, 16).unwrap()) .map(|i| u8::from_str_radix(i, 16).unwrap())
.collect(); .collect();
println!(" Len is : {}, is it modulo 3-bytes ? {}", // TODO !
&hex.len(), // TODO: Make not ugly and move to function b64_encode(Vec<u8>) -> str
if &hex.len()%3 == 0 { "true" } else { "false"} // TODO !
); let mut output = String::new();
print!("b64_encode({:?}) ==> ", &input_str);
// Ugly right ?
for j in (0..hex.len()).step_by(3) { for j in (0..hex.len()).step_by(3) {
let mut pad = 0;
let mut arr = [0u8;4]; 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; arr[0] = 0;
for i in 0..3 { for i in 0..3 {
arr[i+1] = hex[i+j]; if i+j == hex.len() {
arr[i+1] = 0;
pad = 1;
} else if i+j > hex.len() {
arr[i+1] = 0;
pad = 2;
} else {
arr[i+1] = hex[i+j];
}
} }
let tmp = u32::from_be_bytes(arr); let tmp = u32::from_be_bytes(arr);
let tmp1:usize = ((tmp>>18) & 0x3F).try_into().unwrap(); let tmp1:usize = ((tmp>>18) & 0x3F).try_into().unwrap();
let tmp2:usize = ((tmp>>12) & 0x3F).try_into().unwrap(); let tmp2:usize = ((tmp>>12) & 0x3F).try_into().unwrap();
// If this fail we need to PAD '==' output.push(BASE64_TABLE[tmp1]);
let tmp3:usize = ((tmp>>6) & 0x3F).try_into().unwrap(); output.push(BASE64_TABLE[tmp2]);
// If this fail we need to PAD '='
let tmp4:usize = ((tmp) & 0x3F).try_into().unwrap();
print!("{}", BASE64_TABLE[tmp1]); if pad == 2 {
print!("{}", BASE64_TABLE[tmp2]); output.push_str("==");
print!("{}", BASE64_TABLE[tmp3]); break
print!("{}", BASE64_TABLE[tmp4]); } else {
let tmp3:usize = ((tmp>>6) & 0x3F).try_into().unwrap();
output.push(BASE64_TABLE[tmp3]);
}
if pad == 1 {
output.push_str("=");
break
} else {
let tmp4:usize = ((tmp) & 0x3F).try_into().unwrap();
output.push(BASE64_TABLE[tmp4]);
}
} }
println!();
println!("Input string is '{}'", input);
println!("Hex String to ASCII '{}'", &input_str);
println!("Base64 encode '{}'", output);
} }