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
108 lines
2.0 KiB
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)
|
|
}
|