scsys_crypto/hash/hashes/
h256.rs1use crate::{
7 hash::{generate_random_hash, H160},
8 GenericHash, H256Hash, Hashable,
9};
10use serde::{Deserialize, Serialize};
11
12#[derive(Clone, Copy, Default, Deserialize, Eq, Hash, PartialEq, Serialize)]
14pub struct H256(pub H256Hash);
15
16impl H256 {
17 pub fn new(data: H256Hash) -> Self {
18 Self(data)
19 }
20 pub fn generate() -> Self {
21 generate_random_hash()
22 }
23}
24
25impl Hashable for H256 {
26 fn hash(&self) -> H256 {
27 *self
28 }
29}
30
31impl std::fmt::Debug for H256 {
32 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
33 write!(
34 f,
35 "{:>02x}{:>02x}..{:>02x}{:>02x}",
36 &self.0[0], &self.0[1], &self.0[30], &self.0[31]
37 )
38 }
39}
40
41impl std::fmt::Display for H256 {
42 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
43 let start = if let Some(precision) = f.precision() {
44 if precision >= 64 {
45 0
46 } else {
47 32 - precision / 2
48 }
49 } else {
50 0
51 };
52 for byte_idx in start..32 {
53 write!(f, "{:>02x}", &self.0[byte_idx])?;
54 }
55 Ok(())
56 }
57}
58
59impl std::convert::AsRef<[u8]> for H256 {
60 fn as_ref(&self) -> &[u8] {
61 &self.0
62 }
63}
64
65impl std::convert::From<&[u8; 32]> for H256 {
66 fn from(input: &[u8; 32]) -> H256 {
67 let mut buffer: [u8; 32] = [0; 32];
68 buffer[..].copy_from_slice(input);
69 H256(buffer)
70 }
71}
72
73impl std::convert::From<GenericHash> for H256 {
74 fn from(data: GenericHash) -> H256 {
75 data.as_slice().to_owned().into()
76 }
77}
78
79impl std::convert::From<&H256> for [u8; 32] {
80 fn from(input: &H256) -> [u8; 32] {
81 let mut buffer: [u8; 32] = [0; 32];
82 buffer[..].copy_from_slice(&input.0);
83 buffer
84 }
85}
86
87impl std::convert::From<[u8; 32]> for H256 {
88 fn from(input: [u8; 32]) -> H256 {
89 H256(input)
90 }
91}
92
93impl std::convert::From<H160> for H256 {
94 fn from(input: H160) -> H256 {
95 let mut buffer: H256Hash = [0; 32];
96 buffer[..].copy_from_slice(&input.0[0..20]);
97 buffer.into()
98 }
99}
100
101impl std::convert::From<H256> for [u8; 32] {
102 fn from(input: H256) -> [u8; 32] {
103 input.0
104 }
105}
106
107impl std::convert::From<Vec<u8>> for H256 {
108 fn from(input: Vec<u8>) -> H256 {
109 let mut raw_hash: [u8; 32] = [0; 32];
110 raw_hash[0..32].copy_from_slice(input.as_ref());
111 H256(raw_hash)
112 }
113}
114
115impl std::convert::From<ring::digest::Digest> for H256 {
116 fn from(input: ring::digest::Digest) -> H256 {
117 let mut raw_hash: [u8; 32] = [0; 32];
118 raw_hash[0..32].copy_from_slice(input.as_ref());
119 H256(raw_hash)
120 }
121}
122
123impl std::ops::Div<f64> for H256 {
124 type Output = Self;
125
126 fn div(self, rhs: f64) -> Self {
127 let mut result_bytes = [0; 32];
128 for n in 1..9 {
129 let value = u32::from_be_bytes(self.0[4 * (n - 1)..4 * n].try_into().unwrap());
130 let value = value as f64;
131 let result = value / rhs;
132 let result = result as u32;
133 let results: [u8; 4] = result.to_be_bytes();
134 result_bytes[4 * (n - 1)] = results[0];
135 result_bytes[4 * (n - 1) + 1] = results[1];
136 result_bytes[4 * (n - 1) + 2] = results[2];
137 result_bytes[4 * (n - 1) + 3] = results[3];
138 }
139 (&result_bytes).into()
140 }
141}
142
143impl std::ops::Mul<f64> for H256 {
144 type Output = Self;
145
146 fn mul(self, rhs: f64) -> Self {
147 let mut result_bytes = [0; 32];
148 for n in 1..9 {
149 let value = u32::from_be_bytes(self.0[4 * (n - 1)..4 * n].try_into().unwrap());
150 let value = value as f64;
152 let result = value * rhs;
153 let result = result as u32;
154 let results: [u8; 4] = result.to_be_bytes();
155 result_bytes[4 * (n - 1)] = results[0];
157 result_bytes[4 * (n - 1) + 1] = results[1];
158 result_bytes[4 * (n - 1) + 2] = results[2];
159 result_bytes[4 * (n - 1) + 3] = results[3];
160 }
161 (&result_bytes).into()
162 }
163}
164
165impl Ord for H256 {
166 fn cmp(&self, other: &H256) -> std::cmp::Ordering {
167 let self_higher = u128::from_be_bytes(self.0[0..16].try_into().unwrap());
168 let self_lower = u128::from_be_bytes(self.0[16..32].try_into().unwrap());
169 let other_higher = u128::from_be_bytes(other.0[0..16].try_into().unwrap());
170 let other_lower = u128::from_be_bytes(other.0[16..32].try_into().unwrap());
171 let higher = self_higher.cmp(&other_higher);
172 match higher {
173 std::cmp::Ordering::Equal => self_lower.cmp(&other_lower),
174 _ => higher,
175 }
176 }
177}
178
179impl PartialOrd for H256 {
180 fn partial_cmp(&self, other: &H256) -> Option<std::cmp::Ordering> {
181 Some(self.cmp(other))
182 }
183}
184
185#[cfg(test)]
186mod tests {
187 use super::*;
188
189 #[test]
190 fn test_h256_random() {
191 let a = H256::generate();
192 let b = H256::generate();
193 assert_ne!(a, b)
194 }
195
196 #[test]
197 fn test_h256_divide() {
198 let a = H256::generate();
199 assert_eq!(a, a / 1f64);
200 assert_ne!(a, a / 0f64);
201 assert_ne!(a, a / 10f64)
202 }
203
204 #[test]
205 fn test_h256_multiply() {
206 let a = H256::generate();
207 assert_eq!(a, a * 1f64);
208 assert_ne!(a, a * 0f64);
209 assert_ne!(a, a * 10f64)
210 }
211}