use digest::DynDigest;
use failure::Error;
use md5;
use sha1;
use sha2;
use sha3;
#[derive(Debug, Clone, Copy)]
pub enum HashType {
MD5, SHA1, SHA2, SHA3, }
pub fn hex_bits(sum: &str) -> Result<u16, Error> {
if let Some(c) = sum.chars().find(|c| !c.is_digit(16)) {
bail!("Non hexdigit {} found in checksum", c)
} else {
Ok(sum.len() as u16 * 4)
}
}
pub fn digest(hash: HashType, bits: Option<u16>) -> Result<Box<DynDigest>, Error> {
match (hash, bits) {
(HashType::MD5, Some(128)) => Ok(Box::new(md5::Md5::default())),
(HashType::MD5, None) => Ok(Box::new(md5::Md5::default())),
(HashType::SHA1, Some(160)) => Ok(Box::new(sha1::Sha1::default())),
(HashType::SHA1, None) => Ok(Box::new(sha1::Sha1::default())),
(HashType::SHA2, Some(224)) => Ok(Box::new(sha2::Sha224::default())),
(HashType::SHA2, Some(256)) => Ok(Box::new(sha2::Sha256::default())),
(HashType::SHA2, Some(384)) => Ok(Box::new(sha2::Sha384::default())),
(HashType::SHA2, Some(512)) => Ok(Box::new(sha2::Sha512::default())),
(HashType::SHA2, None) => Ok(Box::new(sha2::Sha512::default())),
(HashType::SHA3, Some(224)) => Ok(Box::new(sha3::Sha3_224::default())),
(HashType::SHA3, Some(256)) => Ok(Box::new(sha3::Sha3_256::default())),
(HashType::SHA3, Some(384)) => Ok(Box::new(sha3::Sha3_384::default())),
(HashType::SHA3, Some(512)) => Ok(Box::new(sha3::Sha3_512::default())),
(HashType::SHA3, None) => Ok(Box::new(sha3::Sha3_512::default())),
_ => bail!(
"{:?} with length {} ({} bits) is invalid; double check entered checksum",
&hash,
bits.unwrap() / 4,
bits.unwrap()
),
}
}