key.go 1.2 KB
Newer Older
Petar Maymounkov's avatar
Petar Maymounkov committed
1 2
package key

3 4
import (
	"bytes"
5
	"encoding/json"
6
	"fmt"
7
	"math/big"
8
	"strings"
9

tavit ohanian's avatar
tavit ohanian committed
10
	kbucket "gitlab.dms3.io/p2p/go-p2p-kbucket"
11
)
Petar Maymounkov's avatar
Petar Maymounkov committed
12

13
func KbucketIDToKey(id kbucket.ID) Key {
14
	return Key(id)
15 16
}

17 18 19 20 21 22 23 24 25
func ByteKey(b byte) Key {
	return Key{b}
}

func BytesKey(b []byte) Key {
	return Key(b)
}

// Key is a vector of bits backed by a Go byte slice.
26
// First byte is most significant.
27
// First bit (in each byte) is least significant.
Petar Maymounkov's avatar
Petar Maymounkov committed
28 29
type Key []byte

30
func (k Key) BitAt(offset int) byte {
31
	if k[offset/8]&(byte(1)<<(7-offset%8)) == 0 {
Petar Maymounkov's avatar
Petar Maymounkov committed
32 33 34 35 36 37
		return 0
	} else {
		return 1
	}
}

38
func (k Key) NormInt() *big.Int {
39
	return big.NewInt(0).SetBytes(k)
40 41
}

42 43 44 45 46
func (k Key) BitLen() int {
	return 8 * len(k)
}

func (k Key) String() string {
47 48 49 50
	b, _ := json.Marshal(k)
	return string(b)
}

51
// BitString returns a bit representation of the key, in descending order of significance.
52
func (k Key) BitString() string {
53 54
	s := make([]string, len(k))
	for i, b := range k {
55
		s[i] = fmt.Sprintf("%08b", b)
56 57
	}
	return strings.Join(s, "")
Petar Maymounkov's avatar
Petar Maymounkov committed
58 59 60 61 62
}

func Equal(x, y Key) bool {
	return bytes.Equal(x, y)
}
63 64

func Xor(x, y Key) Key {
65
	z := make(Key, len(x))
66 67 68 69 70 71 72 73 74
	for i := range x {
		z[i] = x[i] ^ y[i]
	}
	return z
}

func DistInt(x, y Key) *big.Int {
	return Xor(x, y).NormInt()
}