1#![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#![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#[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#[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
96pub const XOR_NAME_LEN: usize = 32;
98
99#[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 pub fn from_content(content: &[u8]) -> Self {
117 Self::from_content_parts(&[content])
118 }
119
120 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 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 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 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 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 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 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 }
202 self
203 }
204
205 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 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 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}