2018-09-18 02:36:09 +00:00
|
|
|
package testutil
|
2018-08-14 00:58:37 +00:00
|
|
|
|
2018-10-14 18:35:52 +00:00
|
|
|
import "fmt"
|
|
|
|
|
2018-08-14 00:58:37 +00:00
|
|
|
// CheckBit checks if a bit in a bit field is one.
|
2018-10-14 18:35:52 +00:00
|
|
|
func CheckBit(bitfield []byte, index int) (bool, error) {
|
2018-08-14 00:58:37 +00:00
|
|
|
chunkLocation := (index + 1) / 8
|
|
|
|
indexLocation := (index + 1) % 8
|
|
|
|
if indexLocation == 0 {
|
|
|
|
indexLocation = 8
|
|
|
|
} else {
|
|
|
|
chunkLocation++
|
|
|
|
}
|
2018-10-14 18:35:52 +00:00
|
|
|
|
|
|
|
if chunkLocation > len(bitfield) {
|
|
|
|
return false, fmt.Errorf("index out of range for bitfield: length: %d, position: %d ",
|
|
|
|
len(bitfield), chunkLocation-1)
|
|
|
|
}
|
|
|
|
|
2018-08-14 00:58:37 +00:00
|
|
|
field := bitfield[chunkLocation-1] >> (8 - uint(indexLocation))
|
2018-10-14 18:35:52 +00:00
|
|
|
return field%2 != 0, nil
|
2018-08-14 00:58:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// BitSetCount counts the number of 1s in a byte using the following algo:
|
|
|
|
// https://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel
|
2018-09-15 14:51:17 +00:00
|
|
|
func BitSetCount(bytes []byte) int {
|
|
|
|
var total int
|
|
|
|
for _, b := range bytes {
|
|
|
|
b = (b & 0x55) + ((b >> 1) & 0x55)
|
|
|
|
b = (b & 0x33) + ((b >> 2) & 0x33)
|
|
|
|
total += int((b + (b >> 4)) & 0xF)
|
|
|
|
}
|
|
|
|
return total
|
2018-08-14 00:58:37 +00:00
|
|
|
}
|
2018-08-24 16:07:23 +00:00
|
|
|
|
2018-09-15 14:51:17 +00:00
|
|
|
// BitLength returns the length of the bitfield for a giben number of attesters in bytes.
|
2018-08-24 16:07:23 +00:00
|
|
|
func BitLength(b int) int {
|
|
|
|
return (b + 7) / 8
|
|
|
|
}
|