You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

108 lines
2.0 KiB

4 years ago
use super::*;
use sha2::{
Sha256,
Digest,
};
use std::{
fmt,
io::{
self, Read,
},
};
pub const SHA256_SIZE: usize = 32;
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
pub struct Sha256Hash([u8; SHA256_SIZE]);
impl Sha256Hash
{
pub fn new(from: [u8; SHA256_SIZE]) -> Self
{
Self(from)
}
pub fn from_slice<T>(from: T) -> Self
where T: AsRef<[u8]>
{
let mut out = [0u8; SHA256_SIZE];
bytes::copy_slice(&mut out, from.as_ref());
Self(out)
}
}
impl fmt::Display for Sha256Hash
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "Sha256hash (")?;
for b in self.0.iter()
{
write!(f,"{:02x}", *b)?;
}
write!(f, ")")
}
}
impl Default for Sha256Hash
{
fn default() -> Self
{
Self([0u8; SHA256_SIZE])
}
}
impl From<Sha256> for Sha256Hash
{
fn from(hash: Sha256) -> Sha256Hash
{
let mut out = [0u8; SHA256_SIZE];
assert_eq!(bytes::copy_slice(&mut out, hash.finalize()), SHA256_SIZE);
Self(out)
}
}
impl AsRef<[u8]> for Sha256Hash
{
fn as_ref(&self) -> &[u8]
{
&self.0[..]
}
}
/// Compute SHA256 hash from a stream.
pub fn compute<R: Read>(stream: &mut R, result: &mut Sha256Hash) -> io::Result<usize>
{
let mut buffer = [0u8; BUFFER_SIZE];
let mut read;
let mut done=0;
let mut digest = Sha256::new();
while {read = stream.read(&mut buffer[..])?; read!=0} {
digest.update(&buffer[..read]);
done+=read;
}
*result = digest.into();
Ok(done)
}
/// Compute SHA256 hash from a stream.
#[cfg(feature="threads")]
pub async fn compute_async<R>(stream: &mut R, result: &mut Sha256Hash) -> io::Result<usize>
where R: tokio::io::AsyncRead + std::marker::Send + std::marker::Sync + std::marker::Unpin
{
use tokio::prelude::*;
let mut buffer = [0u8; BUFFER_SIZE];
let mut read;
let mut done=0;
let mut digest = Sha256::new();
while {read = stream.read(&mut buffer[..]).await?; read!=0} {
digest.update(&buffer[..read]);
done+=read;
}
*result = digest.into();
Ok(done)
}