func BetweenIncl(id1, id2, key []byte) bool {
	if CompareID(id1, id2) > 0 {
		return CompareID(id1, key) <= 0 || CompareID(id2, key) >= 0
	}
	return CompareID(id1, key) <= 0 && CompareID(id2, key) >= 0
}
BetweenIncl checks if a key is between two ID, both inclusive
package chord
import (
	"bytes"
	"log"
	"math/big"
	"sync"
)
var (
	two            = big.NewInt(2)
	powerCache     = make(map[uint32]*big.Int, 1)
	powerCacheLock sync.RWMutex
)
func getPower(exp uint32) *big.Int {
	powerCacheLock.RLock()
	power := powerCache[exp]
	powerCacheLock.RUnlock()
	if power == nil {
		power = &big.Int{}
		power.Exp(two, big.NewInt(int64(exp)), nil)
		powerCacheLock.Lock()
		powerCache[exp] = power
		powerCacheLock.Unlock()
	}
	return power
}
func CompareID(id1, id2 []byte) int {
	l1, l2 := len(id1), len(id2)
	if l1 > l2 {
		return -CompareID(id2, id1)
	}
	if l1 < l2 {
		tmp := make([]byte, l2)
		copy(tmp[l2-l1:], id1)
		id1 = tmp
	}
	return bytes.Compare(id1, id2)
}
func BigIntToID(i big.Int, m uint32) []byte {
	b := i.Bytes()
	lb := uint32(len(b))
	lID := m / 8
	if lb < lID {
		id := make([]byte, lID)
		copy(id[lID-lb:], b)
		return id
	}
	if lb > lID {
		log.Println("[WARNING] Big integer has more bytes than ID.")
	}
	return b
}
func IDToBigInt(id []byte) big.Int {
	idInt := big.Int{}
	idInt.SetBytes(id)
	return idInt
}
func Between(id1, id2, key []byte) bool {
	if CompareID(id1, id2) > 0 {
		return CompareID(id1, key) < 0 || CompareID(id2, key) > 0
	}
	return CompareID(id1, key) < 0 && CompareID(id2, key) > 0
}
func BetweenLeftIncl(id1, id2, key []byte) bool {
	if CompareID(id1, id2) > 0 {
		return CompareID(id1, key) <= 0 || CompareID(id2, key) > 0
	}
	return CompareID(id1, key) <= 0 && CompareID(id2, key) > 0
}
func BetweenRightIncl(id1, id2, key []byte) bool {
	if CompareID(id1, id2) > 0 {
		return CompareID(id1, key) < 0 || CompareID(id2, key) >= 0
	}
	return CompareID(id1, key) < 0 && CompareID(id2, key) >= 0
}