Complete set 1 challenge 1.
This commit is contained in:
18
src/main.rs
18
src/main.rs
@@ -1,8 +1,20 @@
|
||||
mod set1;
|
||||
|
||||
use crate::set1::convert_hex_to_base64;
|
||||
use crate::set1::{base64_to_string, bytes_to_base64, to_bytes};
|
||||
|
||||
fn test_set1() {
|
||||
let input = to_bytes("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d");
|
||||
let expected = String::from("SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t");
|
||||
match input {
|
||||
Ok(bytes) => {
|
||||
let output = base64_to_string(bytes_to_base64(bytes));
|
||||
assert_eq!(output, expected);
|
||||
println!("{:?}", output);
|
||||
}
|
||||
Err(e) => println!("Error: {:?}", e),
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world! Does it work?");
|
||||
convert_hex_to_base64();
|
||||
test_set1();
|
||||
}
|
||||
|
||||
66
src/set1.rs
66
src/set1.rs
@@ -1,3 +1,65 @@
|
||||
pub fn convert_hex_to_base64() {
|
||||
println!("We are here too.");
|
||||
use std::num::ParseIntError;
|
||||
use std::str;
|
||||
|
||||
pub fn to_bytes(s: &str) -> Result<Vec<u8>, String> {
|
||||
if s.len() % 2 != 0 {
|
||||
return Err(String::from("Input string has uneven number of characters"));
|
||||
}
|
||||
|
||||
let bytes_result: Result<Vec<u8>, ParseIntError> = (0..s.len())
|
||||
.step_by(2)
|
||||
.map(|i| u8::from_str_radix(&s[i..i + 2], 16))
|
||||
.collect();
|
||||
|
||||
match bytes_result {
|
||||
Ok(b) => Ok(b),
|
||||
Err(_) => Err(String::from("Could not convert all digit pairs to hex.")),
|
||||
}
|
||||
}
|
||||
|
||||
fn chunk_to_base64(c: &[u8]) -> Vec<u8> {
|
||||
let (value, iterations) = match c.len() {
|
||||
0 => return vec![],
|
||||
1 => ((c[0] as u32) << 16, 2),
|
||||
2 => ((c[0] as u32) << 16 | (c[1] as u32) << 8, 3),
|
||||
3 => ((c[0] as u32) << 16 | (c[1] as u32) << 8 | (c[2] as u32), 4),
|
||||
_ => panic!("Unexpected number of chunks {}.", c.len()),
|
||||
};
|
||||
(0..iterations)
|
||||
.map(|i| (value.rotate_right((3 - i) * 6) & 0b111111) as u8)
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn bytes_to_base64(bytes: Vec<u8>) -> Vec<u8> {
|
||||
bytes
|
||||
.chunks(3)
|
||||
.map(|c| chunk_to_base64(c))
|
||||
.flatten()
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn base64_to_string(digits: Vec<u8>) -> String {
|
||||
let mut r: Vec<u8> = digits
|
||||
.iter()
|
||||
.map(|d| match d {
|
||||
0..=25 => *d + ('A' as u8),
|
||||
26..=51 => *d - 26 + ('a' as u8),
|
||||
52..=61 => *d - 52 + ('0' as u8),
|
||||
62 => '+' as u8,
|
||||
63 => '/' as u8,
|
||||
_ => panic!("Unexpected base64 digit '{}'", d),
|
||||
})
|
||||
.collect();
|
||||
// Handle padding
|
||||
let pad = '=' as u8;
|
||||
match r.len() % 4 {
|
||||
0 => (),
|
||||
2 => {
|
||||
r.push(pad);
|
||||
r.push(pad);
|
||||
}
|
||||
3 => r.push(pad),
|
||||
_ => (),
|
||||
}
|
||||
str::from_utf8(r.as_slice()).unwrap().to_string()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user