1use crate::structs::{ErrorInfo, HashType};
2use crate::{bytes_data, from_hex, Hash, HashFormatType, RgResult, SafeOption};
3use std::fmt::Display;
4
5use crate::proto_serde::ProtoSerde;
6use sha3::{Digest, Sha3_256};
7
8
9pub trait ToHashed {
10 fn to_hashed(&self) -> Hash;
11}
12
13impl ToHashed for String {
14 fn to_hashed(&self) -> Hash {
15 Hash::from_string_calculate(&*self)
16 }
17}
18
19impl Hash {
20
21 pub fn raw_bytes_hex(&self) -> RgResult<String> {
22 Ok(hex::encode(self.raw_bytes()?))
23 }
24 pub fn raw_bytes(&self) -> RgResult<Vec<u8>> {
26 Ok(self.bytes.safe_get()?.clone().value)
27 }
28 pub fn vec(&self) -> Vec<u8> {
29 self.proto_serialize()
30 }
31 pub fn hex(&self) -> String {
32 hex::encode(self.vec())
33 }
34
35 pub fn new_from_proto(vec: Vec<u8>) -> RgResult<Self> {
36 Hash::proto_deserialize(vec)
37 }
38
39 pub fn new_direct_transaction(vec: &Vec<u8>) -> Self {
40 Self {
41 bytes: bytes_data(vec.clone()),
42 hash_format_type: HashFormatType::Sha3256 as i32,
43 hash_type: HashType::Transaction as i32,
44 }
45 }
46
47 pub fn from_raw_hex_transaction(h: impl Into<String>) -> RgResult<Self> {
49 let bytes = from_hex(h.into())?;
50 let hash = Self::new_direct_transaction(&bytes);
51 hash.validate_size()?;
52 Ok(hash)
53 }
54
55 pub fn validate_size(&self) -> Result<&Self, ErrorInfo> {
56 let i = self.raw_bytes()?.len();
57 if i == 32 {
59 Ok(self)
60 } else {
61 Err(ErrorInfo::error_info("Invalid hash size"))
62 }
63 }
64
65
66 pub fn from_hex<S: Into<String>>(s: S) -> Result<Self, ErrorInfo> {
68 let bytes = from_hex(s.into())?;
69 let hash = Self::new_from_proto(bytes)?;
70 hash.validate_size()?;
71 Ok(hash)
72 }
73
74 pub fn from_string_calculate(s: &str) -> Self {
75 Self::digest(s.as_bytes().to_vec())
76 }
77
78 pub fn digest(s: Vec<u8>) -> Self {
79 Self::new_direct_transaction(&Sha3_256::digest(&s).to_vec())
80 }
81
82 pub fn div_mod(&self, bucket: usize) -> i64 {
83 self.vec().iter().map(|i| i64::from(i.clone())).sum::<i64>() % (bucket as i64)
84 }
85
86 pub fn merkle_combine(&self, right: Hash) -> Self {
87 let mut vec = self.vec();
88 vec.extend(right.vec());
89 Self::digest(vec)
90 }
91
92 pub fn checksum_no_calc(&self) -> Vec<u8> {
93 self.raw_bytes().expect("b")[0..4].to_vec()
94 }
95
96 pub fn checksum_hex(&self) -> String {
97 hex::encode(self.checksum_no_calc())
98 }
99
100 pub fn xor_vec(&self, other: Hash) -> Vec<u8> {
101 let v1 = self.vec();
102 let v2 = other.vec();
103 let xor_value: Vec<u8> = v1
104 .iter()
105 .zip(v2.iter())
106 .map(|(&x1, &x2)| x1 ^ x2)
107 .collect();
108 xor_value
109 }
110
111 pub fn xor_distance(&self, other: Hash) -> u64 {
112 let xor_value = self.xor_vec(other);
113 let distance: u64 = xor_value.iter().map(|&byte| u64::from(byte)).sum();
114 distance
115 }
116
117 pub fn new_checksum(s: &Vec<u8>) -> String {
118 Self::digest(s.clone()).checksum_hex()
119 }
120
121}
122
123#[test]
124fn hash_rendering() {
125
126 let h = Hash::from_string_calculate("test");
127 println!("hash: {} {}", h.hex(), h.hex().len());
128 let raw = hex::encode(h.raw_bytes().expect("works"));
129 println!("hash raw bytes: {} len {}", raw, raw.len());
130 }