Implement conversion from base64 into bytes.
This commit is contained in:
@@ -12,30 +12,47 @@ impl std::fmt::Display for BytesBase64 {
|
||||
|
||||
impl BytesBase64 {
|
||||
pub fn from_bytes(Bytes(bytes): Bytes) -> BytesBase64 {
|
||||
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()
|
||||
fn to_base64(c: &[u8]) -> Vec<u8> {
|
||||
let mut v = c.to_vec();
|
||||
// pad with bytes for conversion
|
||||
while v.len() < 3 {
|
||||
v.push(0);
|
||||
}
|
||||
BytesBase64(
|
||||
bytes
|
||||
.chunks(3)
|
||||
.map(|c| chunk_to_base64(c))
|
||||
.flatten()
|
||||
.collect(),
|
||||
)
|
||||
let mut result = vec![
|
||||
(v[0] & 0b11111100) >> 2,
|
||||
(v[0] & 0b00000011) << 4 | (v[1] & 0b11110000) >> 4,
|
||||
(v[1] & 0b00001111) << 2 | (v[2] & 0b11000000) >> 6,
|
||||
(v[2] & 0b00111111) << 0,
|
||||
];
|
||||
// removed padded bytes
|
||||
for _ in c.len()..3 {
|
||||
result.pop();
|
||||
}
|
||||
result
|
||||
}
|
||||
BytesBase64(bytes.chunks(3).map(|c| to_base64(c)).flatten().collect())
|
||||
}
|
||||
|
||||
pub fn to_bytes(&self) -> Bytes {
|
||||
Bytes(vec![])
|
||||
let BytesBase64(v) = self;
|
||||
fn chunk_to_bytes(c: &[u8]) -> Vec<u8> {
|
||||
let mut v = c.to_vec();
|
||||
// pad with bytes for conversion
|
||||
while v.len() < 4 {
|
||||
v.push(0);
|
||||
}
|
||||
let mut result: Vec<u8> = vec![
|
||||
((v[0] & 0b00111111) << 2) | ((v[1] & 0b00110000) >> 4),
|
||||
((v[1] & 0b00001111) << 4) | ((v[2] & 0b00111100) >> 2),
|
||||
((v[2] & 0b00000011) << 6) | ((v[3] & 0b00111111) >> 0),
|
||||
];
|
||||
// removed padded bytes
|
||||
for _ in c.len()..4 {
|
||||
result.pop();
|
||||
}
|
||||
result
|
||||
}
|
||||
Bytes(v.chunks(4).map(|c| chunk_to_bytes(c)).flatten().collect())
|
||||
}
|
||||
|
||||
pub fn from_base64(s: &str) -> BytesBase64 {
|
||||
@@ -75,7 +92,7 @@ impl BytesBase64 {
|
||||
r.push(pad);
|
||||
}
|
||||
3 => r.push(pad),
|
||||
_ => (),
|
||||
_ => panic!("Unexpected lenght for padding '{}'", r.len()),
|
||||
}
|
||||
str::from_utf8(r.as_slice()).unwrap().to_string()
|
||||
}
|
||||
|
||||
10
src/main.rs
10
src/main.rs
@@ -3,10 +3,10 @@ mod bytes_base64;
|
||||
mod set1;
|
||||
|
||||
fn main() {
|
||||
// set1::challenge1();
|
||||
// set1::challenge2();
|
||||
// set1::challenge3();
|
||||
// set1::challenge4();
|
||||
// set1::challenge5();
|
||||
set1::challenge1();
|
||||
set1::challenge2();
|
||||
set1::challenge3();
|
||||
set1::challenge4();
|
||||
set1::challenge5();
|
||||
set1::challenge6();
|
||||
}
|
||||
|
||||
21
src/set1.rs
21
src/set1.rs
@@ -72,12 +72,12 @@ pub fn challenge5() {
|
||||
}
|
||||
|
||||
pub fn challenge6() {
|
||||
fn read(path: &str) -> BytesBase64 {
|
||||
fn read(path: &str) -> Bytes {
|
||||
let s = std::fs::read_to_string(path).unwrap();
|
||||
BytesBase64::from_base64(&s)
|
||||
BytesBase64::from_base64(&s).to_bytes()
|
||||
}
|
||||
|
||||
fn write(path: &str, bytes_base64: &BytesBase64) {
|
||||
fn _write(path: &str, bytes_base64: &BytesBase64) {
|
||||
let width = 60;
|
||||
let bytes = bytes_base64.to_string();
|
||||
let mut output_vec = vec![];
|
||||
@@ -88,12 +88,19 @@ pub fn challenge6() {
|
||||
}
|
||||
output_vec.push(*e.0);
|
||||
}
|
||||
|
||||
output_vec.push('\n' as u8);
|
||||
let mut f = std::fs::File::create(path).unwrap();
|
||||
f.write(&output_vec).unwrap();
|
||||
}
|
||||
|
||||
let bytes_base64 = read("data/6.txt");
|
||||
write("data/6_out.txt", &bytes_base64);
|
||||
println!("[open] Challenge 6");
|
||||
fn _test_roundtrip() {
|
||||
// Test that conversion from to bytes and back works
|
||||
let bytes = read("data/6.txt");
|
||||
let bytes_base64 = BytesBase64::from_bytes(bytes);
|
||||
_write("data/6.txt", &bytes_base64);
|
||||
}
|
||||
|
||||
_test_roundtrip();
|
||||
let _bytes = read("data/6.txt");
|
||||
println!("[open] Challenge 6: {}", 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user