xor_name/
lib.rs

1// Copyright 2021 MaidSafe.net limited.
2//
3// This SAFE Network Software is licensed to you under the MIT license <LICENSE-MIT
4// http://opensource.org/licenses/MIT> or the Modified BSD license <LICENSE-BSD
5// https://opensource.org/licenses/BSD-3-Clause>, at your option. This file may not be copied,
6// modified, or distributed except according to those terms. Please review the Licences for the
7// specific language governing permissions and limitations relating to use of the SAFE Network
8// Software.
9
10//! # xor_name
11//!
12//! TODO requires further documentation.
13
14#![doc(
15    html_logo_url = "https://raw.githubusercontent.com/maidsafe/QA/master/Images/maidsafe_logo.png",
16    html_favicon_url = "http://maidsafe.net/img/favicon.ico",
17    html_root_url = "http://maidsafe.github.io/xor_name"
18)]
19// For explanation of lint checks, run `rustc -W help` or see
20// https://github.com/maidsafe/QA/blob/master/Documentation/Rust%20Lint%20Checks.md
21#![forbid(mutable_transmutes, no_mangle_const_items, unknown_crate_types)]
22#![deny(
23    deprecated,
24    improper_ctypes,
25    missing_docs,
26    non_shorthand_field_patterns,
27    overflowing_literals,
28    stable_features,
29    unconditional_recursion,
30    unknown_lints,
31    unsafe_code,
32    unused,
33    unused_allocation,
34    unused_attributes,
35    unused_comparisons,
36    unused_features,
37    unused_parens,
38    while_true,
39    warnings
40)]
41#![warn(
42    trivial_casts,
43    trivial_numeric_casts,
44    unused_extern_crates,
45    unused_import_braces,
46    unused_qualifications,
47    unused_results
48)]
49#![allow(
50    box_pointers,
51    missing_copy_implementations,
52    missing_debug_implementations,
53    variant_size_differences
54)]
55
56use core::{cmp::Ordering, fmt, ops};
57pub use prefix::Prefix;
58pub use rand;
59use rand::distributions::{Distribution, Standard};
60use tiny_keccak::{Hasher, Sha3};
61
62/// Creates XorName with the given leading bytes and the rest filled with zeroes.
63#[macro_export]
64macro_rules! xor_name {
65    ($($byte:expr),* $(,)?) => {{
66        let mut name = $crate::XorName::default();
67        let mut index = 0;
68
69        #[allow(unused_assignments)]
70        {
71            $(
72                name.0[index] = $byte;
73                index += 1;
74            )*
75        }
76
77        name
78    }}
79}
80
81// No-std replacement for std::format! macro which returns `ArrayString` instead of `String`. The
82// capacity of the returned `ArrayString` needs to explicitly given as the first argument.
83#[cfg(test)]
84macro_rules! format {
85    ($capacity:expr, $($arg:tt)*) => {{
86        let mut output = arrayvec::ArrayString::<[_; $capacity]>::new();
87        core::fmt::write(&mut output, core::format_args!($($arg)*)).expect("insufficient ArrayString capacity");
88        output
89    }}
90}
91
92mod prefix;
93#[cfg(feature = "serialize-hex")]
94mod serialize;
95
96/// Constant byte length of `XorName`.
97pub const XOR_NAME_LEN: usize = 32;
98
99/// A 256-bit number, viewed as a point in XOR space.
100///
101/// This wraps an array of 32 bytes, i. e. a number between 0 and 2<sup>256</sup> - 1.
102///
103/// XOR space is the space of these numbers, with the [XOR metric][1] as a notion of distance,
104/// i. e. the points with IDs `x` and `y` are considered to have distance `x xor y`.
105///
106/// [1]: https://en.wikipedia.org/wiki/Kademlia#System_details
107#[derive(Eq, Copy, Clone, Default, Hash, Ord, PartialEq, PartialOrd)]
108#[cfg_attr(
109    not(feature = "serialize-hex"),
110    derive(serde::Serialize, serde::Deserialize)
111)]
112pub struct XorName(pub [u8; XOR_NAME_LEN]);
113
114impl XorName {
115    /// Generate a XorName for the given content.
116    pub fn from_content(content: &[u8]) -> Self {
117        Self::from_content_parts(&[content])
118    }
119
120    /// Generate a XorName for the given content (for content-addressable-storage)
121    pub fn from_content_parts(content_parts: &[&[u8]]) -> Self {
122        let mut sha3 = Sha3::v256();
123        for part in content_parts {
124            sha3.update(part);
125        }
126        let mut hash = [0u8; XOR_NAME_LEN];
127        sha3.finalize(&mut hash);
128        Self(hash)
129    }
130
131    /// Generate a random XorName
132    pub fn random<T: rand::Rng>(rng: &mut T) -> Self {
133        let mut xor = [0u8; XOR_NAME_LEN];
134        rng.fill(&mut xor);
135        Self(xor)
136    }
137
138    /// Returns `true` if the `i`-th bit is `1`.
139    pub fn bit(&self, i: u8) -> bool {
140        let index = i / 8;
141        let pow_i = 1 << (7 - (i % 8));
142        self[index as usize] & pow_i != 0
143    }
144
145    /// Compares the distance of the arguments to `self`. Returns `Less` if `lhs` is closer,
146    /// `Greater` if `rhs` is closer, and `Equal` if `lhs == rhs`. (The XOR distance can only be
147    /// equal if the arguments are equal.)
148    pub fn cmp_distance(&self, lhs: &Self, rhs: &Self) -> Ordering {
149        for i in 0..XOR_NAME_LEN {
150            if lhs[i] != rhs[i] {
151                return Ord::cmp(&(lhs[i] ^ self[i]), &(rhs[i] ^ self[i]));
152            }
153        }
154        Ordering::Equal
155    }
156
157    /// Returns a copy of `self`, with the `i`-th bit set to `bit`.
158    ///
159    /// If `i` exceeds the number of bits in `self`, an unmodified copy of `self` is returned.
160    pub fn with_bit(mut self, i: u8, bit: bool) -> Self {
161        if i as usize >= XOR_NAME_LEN * 8 {
162            return self;
163        }
164        let pow_i = 1 << (7 - i % 8);
165        if bit {
166            self.0[i as usize / 8] |= pow_i;
167        } else {
168            self.0[i as usize / 8] &= !pow_i;
169        }
170        self
171    }
172
173    /// Returns a copy of `self`, with the `i`-th bit flipped.
174    ///
175    /// If `i` exceeds the number of bits in `self`, an unmodified copy of `self` is returned.
176    fn with_flipped_bit(mut self, i: u8) -> Self {
177        if i as usize >= XOR_NAME_LEN * 8 {
178            return self;
179        }
180        self.0[i as usize / 8] ^= 1 << (7 - i % 8);
181        self
182    }
183
184    /// Returns a copy of self with first `n` bits preserved, and remaining bits
185    /// set to 0 (val == false) or 1 (val == true).
186    fn set_remaining(mut self, n: u8, val: bool) -> Self {
187        for (i, x) in self.0.iter_mut().enumerate() {
188            let i = i as u8;
189
190            if n <= i * 8 {
191                *x = if val { !0 } else { 0 };
192            } else if n < (i + 1) * 8 {
193                let mask = !0 >> (n - i * 8);
194                if val {
195                    *x |= mask
196                } else {
197                    *x &= !mask
198                }
199            }
200            // else n >= (i+1) * bits: nothing to do
201        }
202        self
203    }
204
205    /// Returns the length of the common prefix with the `other` name; e. g.
206    /// the when `other = 11110000` and `self = 11111111` this is 4.
207    fn common_prefix(&self, other: &Self) -> usize {
208        for byte_index in 0..XOR_NAME_LEN {
209            if self[byte_index] != other[byte_index] {
210                return (byte_index * 8)
211                    + (self[byte_index] ^ other[byte_index]).leading_zeros() as usize;
212            }
213        }
214        8 * XOR_NAME_LEN
215    }
216}
217
218impl fmt::Debug for XorName {
219    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
220        write!(
221            formatter,
222            "{:02x}{:02x}{:02x}({:08b})..",
223            self[0], self[1], self[2], self
224        )
225    }
226}
227
228impl fmt::Display for XorName {
229    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
230        write!(formatter, "{:02x}{:02x}{:02x}..", self[0], self[1], self[2])
231    }
232}
233
234impl fmt::Binary for XorName {
235    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
236        if let Some(width) = formatter.width() {
237            let whole_bytes = width / 8;
238            let remaining_bits = width % 8;
239
240            for byte in &self[..whole_bytes] {
241                write!(formatter, "{:08b}", byte)?
242            }
243
244            for bit in 0..remaining_bits {
245                write!(formatter, "{}", (self[whole_bytes] >> (7 - bit)) & 1)?;
246            }
247
248            if formatter.alternate() && whole_bytes < XOR_NAME_LEN - 1 {
249                write!(formatter, "..")?;
250            }
251        } else {
252            for byte in &self[..] {
253                write!(formatter, "{:08b}", byte)?
254            }
255        }
256        Ok(())
257    }
258}
259
260impl fmt::LowerHex for XorName {
261    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
262        let bytes = formatter.width().unwrap_or(2 * XOR_NAME_LEN) / 2;
263
264        for byte in &self[..bytes] {
265            write!(formatter, "{:02x}", byte)?;
266        }
267
268        if formatter.alternate() && bytes < XOR_NAME_LEN {
269            write!(formatter, "..")?;
270        }
271
272        Ok(())
273    }
274}
275
276impl fmt::UpperHex for XorName {
277    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
278        let bytes = formatter.width().unwrap_or(2 * XOR_NAME_LEN) / 2;
279
280        for byte in &self[..bytes] {
281            write!(formatter, "{:02X}", byte)?;
282        }
283
284        if formatter.alternate() && bytes < XOR_NAME_LEN {
285            write!(formatter, "..")?;
286        }
287
288        Ok(())
289    }
290}
291
292impl Distribution<XorName> for Standard {
293    fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> XorName {
294        let mut name = XorName::default();
295        rng.fill(&mut name.0[..]);
296        name
297    }
298}
299
300impl ops::Not for XorName {
301    type Output = Self;
302
303    fn not(mut self) -> Self {
304        for byte in &mut self.0 {
305            *byte = !*byte;
306        }
307        self
308    }
309}
310
311impl AsRef<XorName> for XorName {
312    fn as_ref(&self) -> &Self {
313        self
314    }
315}
316
317impl AsRef<[u8]> for XorName {
318    fn as_ref(&self) -> &[u8] {
319        &self.0[..]
320    }
321}
322
323impl ops::Deref for XorName {
324    type Target = [u8];
325
326    fn deref(&self) -> &Self::Target {
327        &self.0[..]
328    }
329}
330
331#[cfg(test)]
332mod tests {
333    use super::*;
334    use bincode::{deserialize, serialize};
335    use rand::{rngs::SmallRng, Rng, SeedableRng};
336
337    #[test]
338    fn create_random_xorname() {
339        let mut rng = SmallRng::from_entropy();
340        let xorname: XorName = XorName::random(&mut rng);
341        let xorname2: XorName = XorName::random(&mut rng);
342
343        assert_ne!(xorname, xorname2);
344    }
345
346    #[test]
347    fn serialisation_xor_name() {
348        let mut rng = SmallRng::from_entropy();
349        let obj_before: XorName = XorName::random(&mut rng);
350        let data = serialize(&obj_before).unwrap();
351        assert_eq!(data.len(), XOR_NAME_LEN);
352        let obj_after: XorName = deserialize(&data).unwrap();
353        assert_eq!(obj_before, obj_after);
354    }
355
356    #[test]
357    #[allow(clippy::eq_op, clippy::nonminimal_bool)]
358    fn xor_name_ord() {
359        let type1: XorName = XorName([1u8; XOR_NAME_LEN]);
360        let type2: XorName = XorName([2u8; XOR_NAME_LEN]);
361        assert_eq!(Ord::cmp(&type1, &type1), Ordering::Equal);
362        assert_eq!(Ord::cmp(&type1, &type2), Ordering::Less);
363        assert_eq!(Ord::cmp(&type2, &type1), Ordering::Greater);
364        assert!(type1 < type2);
365        assert!(type1 <= type2);
366        assert!(type1 <= type1);
367        assert!(type2 > type1);
368        assert!(type2 >= type1);
369        assert!(type1 >= type1);
370        assert!(!(type2 < type1));
371        assert!(!(type2 <= type1));
372        assert!(!(type1 > type2));
373        assert!(!(type1 >= type2));
374    }
375
376    #[test]
377    #[allow(clippy::nonminimal_bool)]
378    fn xor_name_equal_assertion() {
379        let mut rng = SmallRng::from_entropy();
380        let type1: XorName = rng.gen();
381        let type1_clone = type1;
382        let type2: XorName = rng.gen();
383        assert_eq!(type1, type1_clone);
384        assert!(!(type1 != type1_clone));
385        assert_ne!(type1, type2);
386    }
387
388    #[test]
389    fn format_debug() {
390        assert_eq!(
391            &format!(18, "{:?}", xor_name!(0x01, 0x23, 0x45, 0x67)),
392            "012345(00000001).."
393        );
394        assert_eq!(
395            &format!(18, "{:?}", xor_name!(0x89, 0xab, 0xcd, 0xdf)),
396            "89abcd(10001001).."
397        );
398    }
399
400    #[test]
401    fn format_hex() {
402        assert_eq!(
403            &format!(64, "{:x}", xor_name!(0x01, 0x23, 0xab)),
404            "0123ab0000000000000000000000000000000000000000000000000000000000"
405        );
406        assert_eq!(&format!(2, "{:2x}", xor_name!(0x01, 0x23, 0xab)), "01");
407        assert_eq!(&format!(4, "{:4x}", xor_name!(0x01, 0x23, 0xab)), "0123");
408        assert_eq!(&format!(6, "{:6x}", xor_name!(0x01, 0x23, 0xab)), "0123ab");
409        assert_eq!(
410            &format!(8, "{:8x}", xor_name!(0x01, 0x23, 0xab)),
411            "0123ab00"
412        );
413        assert_eq!(
414            &format!(10, "{:10x}", xor_name!(0x01, 0x23, 0xab)),
415            "0123ab0000"
416        );
417        assert_eq!(
418            &format!(8, "{:8X}", xor_name!(0x01, 0x23, 0xab)),
419            "0123AB00"
420        );
421
422        assert_eq!(
423            &format!(8, "{:#6x}", xor_name!(0x01, 0x23, 0xab)),
424            "0123ab.."
425        );
426
427        // odd widths are truncated to nearest even
428        assert_eq!(&format!(2, "{:3x}", xor_name!(0x01, 0x23, 0xab)), "01");
429        assert_eq!(&format!(4, "{:5x}", xor_name!(0x01, 0x23, 0xab)), "0123");
430    }
431
432    #[test]
433    fn format_binary() {
434        assert_eq!(
435            &format!(256, "{:b}", xor_name!(0b00001111, 0b01010101)),
436            "00001111010101010000000000000000000000000000000000000000000000000000000000000000000000\
437             00000000000000000000000000000000000000000000000000000000000000000000000000000000000000\
438             000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
439        );
440        assert_eq!(&format!(1, "{:1b}", xor_name!(0b00001111, 0b01010101)), "0");
441        assert_eq!(
442            &format!(2, "{:2b}", xor_name!(0b00001111, 0b01010101)),
443            "00"
444        );
445        assert_eq!(
446            &format!(3, "{:3b}", xor_name!(0b00001111, 0b01010101)),
447            "000"
448        );
449        assert_eq!(
450            &format!(4, "{:4b}", xor_name!(0b00001111, 0b01010101)),
451            "0000"
452        );
453        assert_eq!(
454            &format!(5, "{:5b}", xor_name!(0b00001111, 0b01010101)),
455            "00001"
456        );
457        assert_eq!(
458            &format!(6, "{:6b}", xor_name!(0b00001111, 0b01010101)),
459            "000011"
460        );
461        assert_eq!(
462            &format!(7, "{:7b}", xor_name!(0b00001111, 0b01010101)),
463            "0000111"
464        );
465        assert_eq!(
466            &format!(8, "{:8b}", xor_name!(0b00001111, 0b01010101)),
467            "00001111"
468        );
469        assert_eq!(
470            &format!(9, "{:9b}", xor_name!(0b00001111, 0b01010101)),
471            "000011110"
472        );
473        assert_eq!(
474            &format!(10, "{:10b}", xor_name!(0b00001111, 0b01010101)),
475            "0000111101"
476        );
477        assert_eq!(
478            &format!(16, "{:16b}", xor_name!(0b00001111, 0b01010101)),
479            "0000111101010101"
480        );
481        assert_eq!(
482            &format!(10, "{:#8b}", xor_name!(0b00001111, 0b01010101)),
483            "00001111.."
484        );
485    }
486
487    #[test]
488    fn with_flipped_bit() {
489        let mut rng = SmallRng::from_entropy();
490        let name: XorName = rng.gen();
491        for i in 0..18 {
492            assert_eq!(i, name.common_prefix(&name.with_flipped_bit(i as u8)));
493        }
494        for i in 0..10 {
495            assert_eq!(
496                19 * i,
497                name.common_prefix(&name.with_flipped_bit(19 * i as u8))
498            );
499        }
500    }
501
502    #[test]
503    fn common_prefix() {
504        assert_eq!(
505            0,
506            xor_name!(0b00000000).common_prefix(&xor_name!(0b10000000))
507        );
508        assert_eq!(
509            3,
510            xor_name!(0b11100000).common_prefix(&xor_name!(0b11111111))
511        );
512        assert_eq!(
513            5,
514            xor_name!(0b10101010).common_prefix(&xor_name!(0b10101111))
515        );
516        assert_eq!(
517            0,
518            xor_name!(0, 0, 0, 0).common_prefix(&xor_name!(128, 0, 0, 0))
519        );
520        assert_eq!(
521            11,
522            xor_name!(0, 10, 0, 0).common_prefix(&xor_name!(0, 16, 0, 0))
523        );
524        assert_eq!(
525            31,
526            xor_name!(1, 2, 3, 4).common_prefix(&xor_name!(1, 2, 3, 5))
527        );
528        assert_eq!(
529            256,
530            xor_name!(1, 2, 3, 4).common_prefix(&xor_name!(1, 2, 3, 4))
531        );
532    }
533
534    #[test]
535    fn cmp_distance() {
536        assert_eq!(
537            xor_name!(42).cmp_distance(&xor_name!(13), &xor_name!(13)),
538            Ordering::Equal,
539        );
540        assert_eq!(
541            xor_name!(42).cmp_distance(&xor_name!(44), &xor_name!(45)),
542            Ordering::Less,
543        );
544        assert_eq!(
545            xor_name!(42).cmp_distance(&xor_name!(45), &xor_name!(44)),
546            Ordering::Greater,
547        );
548        assert_eq!(
549            xor_name!(1, 2, 3, 4).cmp_distance(&xor_name!(2, 3, 4, 5), &xor_name!(2, 3, 4, 5)),
550            Ordering::Equal,
551        );
552        assert_eq!(
553            xor_name!(1, 2, 3, 4).cmp_distance(&xor_name!(2, 2, 4, 5), &xor_name!(2, 3, 6, 5)),
554            Ordering::Less,
555        );
556        assert_eq!(
557            xor_name!(1, 2, 3, 4).cmp_distance(&xor_name!(2, 3, 6, 5), &xor_name!(2, 2, 4, 5)),
558            Ordering::Greater,
559        );
560        assert_eq!(
561            xor_name!(1, 2, 3, 4).cmp_distance(&xor_name!(1, 2, 3, 8), &xor_name!(1, 2, 8, 4)),
562            Ordering::Less,
563        );
564        assert_eq!(
565            xor_name!(1, 2, 3, 4).cmp_distance(&xor_name!(1, 2, 8, 4), &xor_name!(1, 2, 3, 8)),
566            Ordering::Greater,
567        );
568        assert_eq!(
569            xor_name!(1, 2, 3, 4).cmp_distance(&xor_name!(1, 2, 7, 4), &xor_name!(1, 2, 6, 4)),
570            Ordering::Less,
571        );
572        assert_eq!(
573            xor_name!(1, 2, 3, 4).cmp_distance(&xor_name!(1, 2, 6, 4), &xor_name!(1, 2, 7, 4)),
574            Ordering::Greater,
575        );
576    }
577
578    #[test]
579    fn bit() {
580        assert!(!xor_name!(0b00101000).bit(0));
581        assert!(xor_name!(0b00101000).bit(2));
582        assert!(!xor_name!(0b00101000).bit(3));
583        assert!(xor_name!(2, 128, 1, 0).bit(6));
584        assert!(xor_name!(2, 128, 1, 0).bit(8));
585        assert!(xor_name!(2, 128, 1, 0).bit(23));
586        assert!(!xor_name!(2, 128, 1, 0).bit(7));
587        assert!(!xor_name!(2, 128, 1, 0).bit(9));
588        assert!(!xor_name!(2, 128, 1, 0).bit(5));
589        assert!(!xor_name!(2, 128, 1, 0).bit(22));
590        assert!(!xor_name!(2, 128, 1, 0).bit(24));
591    }
592
593    #[test]
594    fn set_remaining() {
595        assert_eq!(
596            xor_name!(0b10011011).set_remaining(5, false),
597            xor_name!(0b10011000)
598        );
599        assert_eq!(
600            xor_name!(0b11111111).set_remaining(2, false),
601            xor_name!(0b11000000)
602        );
603        assert_eq!(
604            xor_name!(0b00000000).set_remaining(4, true),
605            xor_name!(
606                0b00001111, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
607                255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
608                255
609            )
610        );
611        assert_eq!(
612            xor_name!(13, 112, 9, 1).set_remaining(0, false),
613            xor_name!(0, 0, 0, 0)
614        );
615        assert_eq!(
616            xor_name!(13, 112, 9, 1).set_remaining(100, false),
617            xor_name!(13, 112, 9, 1)
618        );
619        assert_eq!(
620            xor_name!(13, 112, 9, 1).set_remaining(10, false),
621            xor_name!(13, 64, 0, 0)
622        );
623        assert_eq!(
624            xor_name!(13, 112, 9, 1).set_remaining(10, true),
625            xor_name!(
626                13, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
627                255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
628            )
629        );
630    }
631
632    #[test]
633    fn xor_name_macro() {
634        let mut rng = SmallRng::from_entropy();
635
636        for _ in 0..100 {
637            let byte = rng.gen();
638            assert_eq!(&xor_name!(byte)[..1], &[byte]);
639        }
640
641        for _ in 0..100 {
642            let byte0 = rng.gen();
643            let byte1 = rng.gen();
644            assert_eq!(&xor_name!(byte0, byte1)[..2], &[byte0, byte1]);
645        }
646
647        for _ in 0..100 {
648            let byte0 = rng.gen();
649            let byte1 = rng.gen();
650            let byte2 = rng.gen();
651            assert_eq!(&xor_name!(byte0, byte1, byte2)[..3], &[byte0, byte1, byte2]);
652        }
653    }
654
655    #[test]
656    fn conversion_from_u64() {
657        assert_eq!(
658            &from_u64(0x0123456789abcdef)[XOR_NAME_LEN - 8..],
659            &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]
660        );
661    }
662
663    #[test]
664    fn xor_name_from_content() {
665        let alpha_1 = XorName::from_content_parts(&[b"abcdefg", b"hijk"]);
666        let alpha_2 = XorName::from_content_parts(&[b"abcdefg", b"hijk"]);
667        let alpha_3 = XorName::from_content(b"abcdefg");
668
669        assert_eq!(alpha_1, alpha_2);
670        assert_ne!(alpha_1, alpha_3);
671    }
672
673    #[test]
674    fn xor_name_from_content_is_agnostic_to_where_content_parts_splits() {
675        let alpha_1 = XorName::from_content_parts(&[b"abcdefg", b"hijk"]);
676        let alpha_2 = XorName::from_content(b"abcdefghijk");
677        assert_eq!(alpha_1, alpha_2);
678    }
679
680    // Create a `XorName` with the 8 trailing bytes equal to `x` (in big endian order) and the rest
681    // filled with zeroes.
682    fn from_u64(x: u64) -> XorName {
683        let mut name = XorName::default();
684        name.0[XOR_NAME_LEN - 8..].copy_from_slice(&x.to_be_bytes());
685        name
686    }
687}