I was attempting to use twox-hash to generate a hash for a file, as it seemed to be the fastest hash implementation around and security is not a concern for this implementation.
To get it to work with a reader, I implemented a wrapper struct that implemented the Write
trait and directly called XxHash::write
from the Hash
trait. Is there a more elegant or standard way of doing this?
#[derive(Deref)]
struct HashWriter<T: Hasher>(T);
impl<T: Hasher> std::io::Write for HashWriter<T> {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.0.write(buf);
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
That's what I would do, although I'd also implement write_all
as it can be equally as simple:
use std::{hash::Hasher, io};
struct HashWriter<T: Hasher>(T);
impl<T: Hasher> io::Write for HashWriter<T> {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf);
Ok(buf.len())
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.write(buf).map(|_| ())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
You can then use it like:
use std::fs::File;
use twox_hash::XxHash64;
fn main() {
let mut f = File::open("/etc/hosts").expect("Unable to open file");
let hasher = XxHash64::with_seed(0);
let mut hw = HashWriter(hasher);
io::copy(&mut f, &mut hw).expect("Unable to copy data");
let hasher = hw.0;
println!("{}", hasher.finish());
}
Disclaimer: I am the author / porter of twox-hash.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With