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);
|
||||
}
|
||||
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| chunk_to_base64(c))
|
||||
.flatten()
|
||||
.collect(),
|
||||
)
|
||||
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()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user