57 lines
1.3 KiB
Rust
57 lines
1.3 KiB
Rust
use std::{
|
|
error::Error,
|
|
fmt::{Display, LowerHex},
|
|
};
|
|
|
|
use sha2::Digest;
|
|
|
|
#[derive(Debug)]
|
|
struct Sha256Error {
|
|
message: String,
|
|
}
|
|
|
|
impl Display for Sha256Error {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "{}", self.message)
|
|
}
|
|
}
|
|
impl Error for Sha256Error {}
|
|
|
|
#[derive(Clone, Copy)]
|
|
pub struct Sha256([u8; 32]);
|
|
impl Sha256 {
|
|
pub fn from_hex_string(hex: &str) -> Result<Self, Box<dyn Error>> {
|
|
if hex.len() != 64 {
|
|
return Err(Box::new(Sha256Error {
|
|
message: "sha256 wrong length".to_owned(),
|
|
}));
|
|
}
|
|
|
|
let mut hash = [0; 32];
|
|
hex::decode_to_slice(hex, &mut hash).map_err(|e| Sha256Error {
|
|
message: format!("sha256 decode error: {}", e),
|
|
})?;
|
|
Ok(Self(hash))
|
|
}
|
|
|
|
pub fn from_bytes(bytes: &[u8]) -> Self {
|
|
let hash = sha2::Sha256::digest(bytes);
|
|
Self(hash.into())
|
|
}
|
|
pub fn hex_string(&self) -> String {
|
|
format!("{:x}", self)
|
|
}
|
|
pub fn modulo(&self, num: usize) -> usize {
|
|
self.0[0] as usize % num
|
|
}
|
|
}
|
|
|
|
impl LowerHex for Sha256 {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
for byte in self.0.iter() {
|
|
write!(f, "{:02x}", byte)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|