68 lines
1.6 KiB
Rust
68 lines
1.6 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 {
|
|
let sum: usize = self.0.iter().map(|v| *v as usize).sum();
|
|
sum % 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(())
|
|
}
|
|
}
|
|
|
|
impl PartialEq<String> for Sha256 {
|
|
fn eq(&self, other: &String) -> bool {
|
|
if let Ok(other_sha256) = Sha256::from_hex_string(other) {
|
|
self.0 == other_sha256.0
|
|
} else {
|
|
false
|
|
}
|
|
}
|
|
}
|