The primary reason for migrating is that these crates provide APIs for setting the personalisation string. This enables us to depend solely on published crates, and thus publish our own crates. The SIMD implementations are ported from libsodium. Closes #67.
43 lines
977 B
Rust
43 lines
977 B
Rust
use blake2b_simd::State;
|
|
use std::io::{self, Read};
|
|
|
|
/// Abstraction over a reader which hashes the data being read.
|
|
pub struct HashReader<R: Read> {
|
|
reader: R,
|
|
hasher: State,
|
|
}
|
|
|
|
impl<R: Read> HashReader<R> {
|
|
/// Construct a new `HashReader` given an existing `reader` by value.
|
|
pub fn new(reader: R) -> Self {
|
|
HashReader {
|
|
reader: reader,
|
|
hasher: State::new(),
|
|
}
|
|
}
|
|
|
|
/// Destroy this reader and return the hash of what was read.
|
|
pub fn into_hash(self) -> String {
|
|
let hash = self.hasher.finalize();
|
|
|
|
let mut s = String::new();
|
|
for c in hash.as_bytes().iter() {
|
|
s += &format!("{:02x}", c);
|
|
}
|
|
|
|
s
|
|
}
|
|
}
|
|
|
|
impl<R: Read> Read for HashReader<R> {
|
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
|
let bytes = self.reader.read(buf)?;
|
|
|
|
if bytes > 0 {
|
|
self.hasher.update(&buf[0..bytes]);
|
|
}
|
|
|
|
Ok(bytes)
|
|
}
|
|
}
|