Skip to content

Instantly share code, notes, and snippets.

@AnAverageBeing
Created August 17, 2023 13:25
Show Gist options
  • Save AnAverageBeing/6d8e981b717a729bb771d45aac591543 to your computer and use it in GitHub Desktop.
Save AnAverageBeing/6d8e981b717a729bb771d45aac591543 to your computer and use it in GitHub Desktop.
The bitsarr package facilitates manipulation of arrays of bits in a Big-Endian manner. It enables creation, setting, and retrieval of individual bits within an array, along with generating binary string representations.
package bitsarr
import (
"bytes"
"errors"
)
type bit byte
const (
Zero bit = 0
One bit = 1
)
// Struct to represent an array of bits of arbitrary length
// Big-Endian way
type BitArray struct {
data []byte
bits int
}
// Create and initialize a new BitArray instance with the specified number of bits
func NewBitArray(bits int) (*BitArray, error) {
if bits <= 0 {
return nil, errors.New("invalid number of bits")
}
size := (bits + 7) / 8
data := make([]byte, size)
return &BitArray{
data: data,
bits: bits,
}, nil
}
// SetBit sets the bit at the specified index to the given value (Zero or One)
func (u *BitArray) SetBit(index int, value bit) error {
if index < 0 || index >= u.bits {
return errors.New("index out of range")
}
byteIndex := (u.bits - index - 1) / 8
bitIndex := uint(7 - ((u.bits - index - 1) % 8))
// Clear the target bit and set it to the new value
if value == Zero {
u.data[byteIndex] &^= (1 << bitIndex)
} else {
u.data[byteIndex] |= (1 << bitIndex)
}
return nil
}
// GetBit returns the value of the bit at the specified index (Zero or One)
func (u *BitArray) GetBit(index int) (int, error) {
if index < 0 || index >= u.bits {
return -1, errors.New("index out of range")
}
byteIndex := (u.bits - index - 1) / 8
bitIndex := uint(7 - ((u.bits - index - 1) % 8))
bit := (u.data[byteIndex] >> bitIndex) & 1
return int(bit), nil
}
// String returns a binary string representation of the BitArray instance
func (u BitArray) String() string {
var buf bytes.Buffer
for i := 0; i < u.bits; i++ {
bit, _ := u.GetBit(i)
buf.WriteByte(byte('0' + bit))
}
return buf.String()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment