Files
blob-store-app/src/sha256.rs
2024-04-25 00:26:47 -07:00

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
}
}
}