1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#[macro_use]
mod macros;
pub mod md2;
pub mod md4;
pub trait HashFunction {
fn set_input(&mut self, input: &[u8]);
fn set_input_str(&mut self, input_str: &str) {
self.set_input(input_str.as_bytes());
}
fn hash(&mut self);
fn get_output(&mut self, output: &mut [u8]);
fn get_output_str(&mut self) -> String {
use rustc_serialize::hex::ToHex;
use std::vec::Vec;
let mut output: Vec<u8> = (0..self.get_output_length()).map(|_| 0).collect();
self.get_output(&mut output[..]);
output.to_hex()
}
fn get_blocksize(&self) -> u32;
fn get_output_length_in_bits(&self) -> u32;
fn get_output_length(&self) -> usize {
((self.get_output_length_in_bits() + 7) / 8) as usize
}
}
#[cfg(test)]
mod test {
use hashes::HashFunction;
pub struct HashTestCase {
pub input: &'static str,
pub output: Vec<u8>,
pub output_str: &'static str
}
pub fn perform_hash_test(hash: &mut HashFunction, test: &HashTestCase) {
println!("Testing hash against:\t \"{:2}\"", test.input);
hash.set_input_str(test.input);
hash.hash();
let mut result = Vec::from_elem(hash.get_output_length(), 0u8);
hash.get_output(result.as_mut_slice());
let result_str = hash.get_output_str();
print!("result: \t\t");
for r in result.iter() {
print!("0x{:x} ", *r)
}
println!("");
print!("(expected) output:\t");
for o in test.output.iter() {
print!("0x{:x} ", *o)
}
println!("");
println!("result_str:\t\t{}", result_str);
println!("(expected) output_str:\t{}", test.output_str);
println!("");
assert!(result == test.output);
assert!(result_str.as_slice() == test.output_str);
}
}