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