Fix the hex encoder
This commit is contained in:
parent
3db9fd5dab
commit
589efa5ad6
1 changed files with 33 additions and 2 deletions
35
src/hex.rs
35
src/hex.rs
|
@ -55,11 +55,12 @@ pub trait HexEncodable<T> {
|
|||
pub struct HexEncoder<T> {
|
||||
input: T,
|
||||
current_byte: u8,
|
||||
num_nibbles: u8,
|
||||
}
|
||||
|
||||
impl<T> HexEncoder<T> {
|
||||
pub fn new(input: T) -> HexEncoder<T> {
|
||||
HexEncoder { input: input, current_byte: 0 }
|
||||
HexEncoder { input: input, current_byte: 0, num_nibbles: 0 }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,12 +68,13 @@ impl<'a, T> Iterator for HexEncoder<T> where T: Iterator<Item=u8> + 'a {
|
|||
type Item = char;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.current_byte == 0 {
|
||||
if self.num_nibbles == 0 {
|
||||
// Get a new byte.
|
||||
match self.input.next() {
|
||||
Some(byte) => {
|
||||
// Swap the order of the nibbles to make the code below nicer.
|
||||
self.current_byte = (byte << 4) + (byte >> 4);
|
||||
self.num_nibbles = 2;
|
||||
}
|
||||
None => return None
|
||||
}
|
||||
|
@ -81,6 +83,7 @@ impl<'a, T> Iterator for HexEncoder<T> where T: Iterator<Item=u8> + 'a {
|
|||
match char::from_digit((self.current_byte & 0xF) as u32, 16) {
|
||||
Some(ch) => {
|
||||
self.current_byte = self.current_byte >> 4;
|
||||
self.num_nibbles -= 1;
|
||||
return Some(ch);
|
||||
},
|
||||
None => panic!("This will never happen???")
|
||||
|
@ -107,4 +110,32 @@ mod tests {
|
|||
let decoded: Vec<u8> = "313233".chars().hex_decoded().collect();
|
||||
assert_eq!(decoded, vec![0x31u8, 0x32u8, 0x33u8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cryptopals12_decode() {
|
||||
let a = "1c0111001f010100061a024b53535009181c";
|
||||
let out: Vec<u8> = a.chars().hex_decoded().collect();
|
||||
assert_eq!(out, vec![0x1c, 0x01, 0x11, 0x00, 0x1f, 0x01, 0x01, 0x00,
|
||||
0x06, 0x1a, 0x02, 0x4b, 0x53, 0x53, 0x50, 0x09,
|
||||
0x18, 0x1c]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn each_byte_encodes_to_two_characters() {
|
||||
let input: String = vec![0x06].into_iter().hex_encoded().collect();
|
||||
assert_eq!(input, "06");
|
||||
|
||||
// This was an actual bug, the last nibble was getting eaten. :(
|
||||
let input: String = vec![0x20].into_iter().hex_encoded().collect();
|
||||
assert_eq!(input, "20");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reciprocity_of_encode_and_decode() {
|
||||
let input = "746865206b";
|
||||
let output: String = input.chars()
|
||||
.hex_decoded().inspect(|x| println!("{:08b}", x))
|
||||
.hex_encoded().collect();
|
||||
assert_eq!(input, output);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue