Implement set 1 challenge 3.
This commit is contained in:
87
src/set1.rs
87
src/set1.rs
@@ -8,36 +8,12 @@ pub struct Base64Bytes(Vec<u8>);
|
||||
|
||||
impl std::fmt::Display for Base64Bytes {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let Base64Bytes(digits) = self;
|
||||
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),
|
||||
_ => (),
|
||||
}
|
||||
|
||||
write!(f, "Base64({})", str::from_utf8(r.as_slice()).unwrap())
|
||||
write!(f, "Base64({})", self.to_base64_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl Base64Bytes {
|
||||
pub fn to_string(&self) -> String {
|
||||
pub fn to_base64_string(&self) -> String {
|
||||
let Base64Bytes(digits) = self;
|
||||
let mut r: Vec<u8> = digits
|
||||
.iter()
|
||||
@@ -106,6 +82,7 @@ impl HexBytes {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn to_utf8_string(&self) -> String {
|
||||
let HexBytes(v) = self;
|
||||
String::from(str::from_utf8(&v).unwrap())
|
||||
@@ -120,6 +97,33 @@ impl HexBytes {
|
||||
r
|
||||
}
|
||||
|
||||
fn is_ascii(&self) -> bool {
|
||||
let HexBytes(v) = self;
|
||||
for &c in v.iter() {
|
||||
if c < 32 || c > 127 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn ascii_score(&self) -> u32 {
|
||||
let HexBytes(v) = self;
|
||||
let mut r = 0;
|
||||
for &c in v.iter() {
|
||||
match c {
|
||||
32 => r += 2,
|
||||
33..=64 => r += 1,
|
||||
65..=90 => r += 3,
|
||||
91..=96 => r += 1,
|
||||
97..=122 => r += 3,
|
||||
123..=127 => r += 1,
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
fn xor(HexBytes(a): &HexBytes, HexBytes(b): &HexBytes) -> HexBytes {
|
||||
HexBytes(
|
||||
Iterator::zip(a.iter(), b.iter())
|
||||
@@ -127,14 +131,18 @@ impl HexBytes {
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
||||
fn xor_byte(HexBytes(a): &HexBytes, byte: u8) -> HexBytes {
|
||||
HexBytes(a.iter().map(|e| e ^ byte).collect())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn challenge1() {
|
||||
let input = HexBytes::from_str("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d");
|
||||
let expected = String::from("SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t");
|
||||
let result = input.to_base64();
|
||||
if result.to_string() == expected {
|
||||
println!("[okay] Challenge 1: {}", result);
|
||||
let a = HexBytes::from_str("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d");
|
||||
let e = String::from("SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t");
|
||||
let r = a.to_base64();
|
||||
if r.to_base64_string() == e {
|
||||
println!("[okay] Challenge 1: {}", r);
|
||||
} else {
|
||||
println!("[fail] Challenge 1")
|
||||
}
|
||||
@@ -152,4 +160,19 @@ pub fn challenge2() {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn challenge3() {}
|
||||
pub fn challenge3() {
|
||||
let a =
|
||||
HexBytes::from_str("1b37373331363f78151b7f2b783431333d78397828372d363c78373e783a393b3736");
|
||||
|
||||
let mut h: Vec<HexBytes> = (0..=255).map(|i| HexBytes::xor_byte(&a, i)).collect();
|
||||
h.sort_by(|a, b| a.ascii_score().partial_cmp(&b.ascii_score()).unwrap());
|
||||
let h: Vec<HexBytes> = h.into_iter().filter(|b| b.is_ascii()).collect();
|
||||
let r = h[h.len() - 1].to_utf8_string();
|
||||
let e = String::from("Cooking MC's like a pound of bacon");
|
||||
|
||||
if r == e {
|
||||
println!("[okay] Challenge 3: {}", r);
|
||||
} else {
|
||||
println!("[fail] Challenge 3: {}", r);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user