@@ -62,7 +62,19 @@ impl FromStableHash for Hash64 {
62
62
#[ inline]
63
63
fn from ( hash : Self :: Hash ) -> Self {
64
64
let bytes = hash. as_bytes ( ) ;
65
- Self { inner : u64:: from_ne_bytes ( bytes[ 0 ..8 ] . try_into ( ) . unwrap ( ) ) }
65
+
66
+ let p0 = u64:: from_le_bytes ( bytes[ 0 ..8 ] . try_into ( ) . unwrap ( ) ) ;
67
+ let p1 = u64:: from_le_bytes ( bytes[ 8 ..16 ] . try_into ( ) . unwrap ( ) ) ;
68
+ let p2 = u64:: from_le_bytes ( bytes[ 16 ..24 ] . try_into ( ) . unwrap ( ) ) ;
69
+ let p3 = u64:: from_le_bytes ( bytes[ 24 ..32 ] . try_into ( ) . unwrap ( ) ) ;
70
+
71
+ // See https://stackoverflow.com/a/27952689 on why this function is
72
+ // implemented this way.
73
+ let m0 = p0. wrapping_mul ( 3 ) . wrapping_add ( p1) ;
74
+ let m1 = p2. wrapping_mul ( 3 ) . wrapping_add ( p3) ;
75
+ let h = m0. wrapping_mul ( 3 ) . wrapping_add ( m1) ;
76
+
77
+ Self { inner : h }
66
78
}
67
79
}
68
80
@@ -130,7 +142,18 @@ impl FromStableHash for Hash128 {
130
142
#[ inline]
131
143
fn from ( hash : Self :: Hash ) -> Self {
132
144
let bytes = hash. as_bytes ( ) ;
133
- Self { inner : u128:: from_ne_bytes ( bytes[ 0 ..16 ] . try_into ( ) . unwrap ( ) ) }
145
+
146
+ let p0 = u64:: from_le_bytes ( bytes[ 0 ..8 ] . try_into ( ) . unwrap ( ) ) ;
147
+ let p1 = u64:: from_le_bytes ( bytes[ 8 ..16 ] . try_into ( ) . unwrap ( ) ) ;
148
+ let p2 = u64:: from_le_bytes ( bytes[ 16 ..24 ] . try_into ( ) . unwrap ( ) ) ;
149
+ let p3 = u64:: from_le_bytes ( bytes[ 24 ..32 ] . try_into ( ) . unwrap ( ) ) ;
150
+
151
+ // See https://stackoverflow.com/a/27952689 on why this function is
152
+ // implemented this way.
153
+ let upper = p0. wrapping_mul ( 3 ) . wrapping_add ( p1) ;
154
+ let lower = p2. wrapping_mul ( 3 ) . wrapping_add ( p3) ;
155
+
156
+ Self { inner : u128:: from ( lower) | ( u128:: from ( upper) << 64 ) }
134
157
}
135
158
}
136
159
0 commit comments