proximity.go 1.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package swarm

// Proximity returns the proximity order of the MSB distance between x and y
//
// The distance metric MSB(x, y) of two equal length byte sequences x an y is the
// value of the binary integer cast of the x^y, ie., x and y bitwise xor-ed.
// the binary cast is big endian: most significant bit first (=MSB).
//
// Proximity(x, y) is a discrete logarithmic scaling of the MSB distance.
// It is defined as the reverse rank of the integer part of the base 2
// logarithm of the distance.
// It is calculated by counting the number of common leading zeros in the (MSB)
// binary representation of the x^y.
//
// (0 farthest, 255 closest, 256 self)
20 21
func Proximity(one, other []byte) (ret uint8) {
	b := MaxPO/8 + 1
22 23 24 25
	if l := uint8(len(one)); b > l {
		b = l
	}
	if l := uint8(len(other)); b > l {
26
		b = l
27
	}
28 29
	var m uint8 = 8
	for i := uint8(0); i < b; i++ {
30
		oxo := one[i] ^ other[i]
31 32
		for j := uint8(0); j < m; j++ {
			if (oxo>>(7-j))&0x01 != 0 {
33 34 35 36 37 38
				return i*8 + j
			}
		}
	}
	return MaxPO
}
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

func ExtendedProximity(one, other []byte) (ret uint8) {
	b := ExtendedPO/8 + 1
	if l := uint8(len(one)); b > l {
		b = l
	}
	if l := uint8(len(other)); b > l {
		b = l
	}
	var m uint8 = 8
	for i := uint8(0); i < b; i++ {
		oxo := one[i] ^ other[i]
		for j := uint8(0); j < m; j++ {
			if (oxo>>(7-j))&0x01 != 0 {
				return i*8 + j
			}
		}
	}
	return ExtendedPO
}