You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.1 KiB
136 lines
4.1 KiB
////
|
|
// Cryptopal set 1 chal 1 : https://cryptopals.com/sets/1/challenges/1
|
|
// Run with :
|
|
// cargo run -- 49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d
|
|
////
|
|
|
|
use std::env;
|
|
|
|
/// Convert Hexadecimal Vec<String> to String
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ~~~
|
|
/// let test: Vec<String> = vec![String::from("41"),
|
|
/// String::from("42")];
|
|
/// assert_eq!(hex_to_string(&test), "AB");
|
|
/// ~~~
|
|
fn hex_to_string(hex_char: &Vec<String>) -> String {
|
|
let mut output = String::new();
|
|
// Printing the string in Ascii format - for hexa to Ascii example
|
|
for (i, s) in hex_char.into_iter().enumerate() {
|
|
match u8::from_str_radix(&s, 16).map(|n| n as char) {
|
|
Ok(s) => output.push(s),
|
|
Err(e) => println!("\nError decoding char '{}' at index {}", e, i),
|
|
}
|
|
}
|
|
output
|
|
}
|
|
|
|
/// Encode a Vector of bytes to Base64 and return the base 64 String
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ~~~
|
|
/// let test: Vec<u8> = vec![0x41, 0x42]; // "[A,B] in ascii"
|
|
/// let b64_encode = base64_encode(&test);
|
|
/// assert_eq!(b64_encode, "QUI=");
|
|
/// ~~~
|
|
fn base64_encode(input: &Vec<u8>) -> String {
|
|
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', '+', '/'];
|
|
let mut output = String::new();
|
|
for j in (0..input.len()).step_by(3) {
|
|
let mut pad = 0;
|
|
let mut arr = [0u8;4];
|
|
arr[0] = 0;
|
|
|
|
for i in 0..3 {
|
|
if i+j == input.len() {
|
|
arr[i+1] = 0;
|
|
pad = 1;
|
|
} else if i+j > input.len() {
|
|
arr[i+1] = 0;
|
|
pad = 2;
|
|
} else {
|
|
arr[i+1] = input[i+j];
|
|
}
|
|
}
|
|
let tmp = u32::from_be_bytes(arr);
|
|
|
|
let tmp1 = (tmp>>18) & 0x3F;
|
|
let tmp2 = (tmp>>12) & 0x3F;
|
|
|
|
output.push(BASE64_TABLE[tmp1 as usize]);
|
|
output.push(BASE64_TABLE[tmp2 as usize]);
|
|
|
|
if pad == 2 {
|
|
output.push_str("==");
|
|
break
|
|
} else {
|
|
let tmp3 = (tmp>>6) & 0x3F;
|
|
output.push(BASE64_TABLE[tmp3 as usize]);
|
|
}
|
|
|
|
if pad == 1 {
|
|
output.push_str("=");
|
|
break
|
|
} else {
|
|
let tmp4 = (tmp) & 0x3F;
|
|
output.push(BASE64_TABLE[tmp4 as usize]);
|
|
}
|
|
}
|
|
|
|
output
|
|
}
|
|
|
|
fn main() {
|
|
// Test base64 encode()
|
|
let test: Vec<u8> = vec![0x41, 0x42];
|
|
let b64_encode = base64_encode(&test);
|
|
assert_eq!(b64_encode, "QUI=");
|
|
|
|
// Test hex_to_string()
|
|
let test: Vec<String> = vec![String::from("41"),
|
|
String::from("42")];
|
|
assert_eq!(hex_to_string(&test), "AB");
|
|
|
|
// Get command line argument
|
|
let args: Vec<String> = env::args().collect();
|
|
let input = &args[1];
|
|
let char_vec: Vec<char> = input.chars().collect();
|
|
|
|
// Convert Vec<char> to Vec<String> with 2 hexadecimal chars
|
|
// ie: ['4','1','4','2'] => ["41", "42"]
|
|
let hex_char = &char_vec
|
|
.chunks(2)
|
|
.map(|chunk| chunk.iter().collect::<String>())
|
|
.collect::<Vec<_>>();
|
|
|
|
// 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();
|
|
|
|
// Convert Hexadecimal Vec<String> to String
|
|
// ie: ["41", "42"] => "AB"
|
|
let input_str = hex_to_string(&hex_char);
|
|
|
|
let output = base64_encode(&hex);
|
|
|
|
println!("→ Input string is « {} »", input);
|
|
println!("→ Hex String to ASCII « {} »", &input_str);
|
|
println!("→ Base64 encode « {} »", output);
|
|
}
|
|
|