需要使用版本(4位),计数(3位),标识符(1位)形成标题(8位)数据。如何在Golang中实现?例如:
version: 1 (0001)
count: 3 (011)
identifier: 1(1)
Header: 00010111 (23)
我正在执行以下操作,但是代码繁琐。我如何有效地做到这一点?
const (
VersionSize binary.Bits = 4
countSize binary.Bits = 3
IdentifierSize binary.Bits = 1
)
type header struct {
version uint8
count uint8
identifier uint8
}
func main() {
headerObj := &header{version:1, count:3, identifier:1}
headerBytes := encode(headerObj)
// prints [23]
fmt.PrintLn(headerBytes)
}
func (h *header) encode() []byte {
var header []byte
vercountIdBinary := toBinary(h.version, versionSize) + toBinary(h.count,countSize) + toBinary(h.identifier, IdentifierSize)
vercountIdByte, _ := strconv.ParseInt(vercountIdBinary, 2, 8)
header = append(header, byte(vercountIdByte))
return header
}
func toBinary(value interface{}, bitSize binary.Bits) string {
format := "%0" + strconv.Itoa(int(bitSize)) + "b"
return fmt.Sprintf(format, value)
}
将位打包和解包可以简单地通过位屏蔽和移位实现。
例如,将位打包成一个数字,掩码并分配第一个,然后将结果与位号或下一个数据左移(为其留出足够的空间)。然后屏蔽第二个数字,并使用按位或将其“相加”。然后再次移动第三个数字的大小,然后重复。
解压:用最后一个字段的大小遮盖结果,然后得到最后一个数字。向右移动已解码编号的大小的数据,并以下一个(相反的顺序)编号的大小屏蔽,就得到了编号。重复此过程,直到您解码了所有数字。
例如,将identifier
打包到最高有效位,将count
打包到中间有效位,但version
打包到最低有效位,但是可以通过相反的顺序打包字段来执行相反的顺序:
const (
BitsVersion = 4
BitsCount = 3
BitsId = 1
)
const (
MaskVersion = 1<<BitsVersion - 1
MaskCount = 1<<BitsCount - 1
MaskId = 1<<BitsId - 1
)
type header struct {
version uint8
count uint8
identifier uint8
}
func (h *header) ToByte() uint8 {
var b uint8
b = h.identifier & MaskId
b <<= BitsCount
b |= h.count & MaskCount
b <<= BitsVersion
b |= h.version & MaskVersion
return b
}
func (h *header) ParseByte(b uint8) {
h.version = b & MaskVersion
b >>= BitsVersion
h.count = b & MaskCount
b >>= BitsCount
h.identifier = b & MaskId
}
正在测试:
h := &header{
version: 3,
count: 2,
identifier: 1,
}
fmt.Printf("%+v\n", h)
b := h.ToByte()
h2 := &header{}
h2.ParseByte(b)
fmt.Printf("%+v\n", h2)
将输出(在Go Playground上尝试):
&{version:3 count:2 identifier:1}
&{version:3 count:2 identifier:1}
[请注意,如果您需要针对io.Writer
流,对多个数据进行此操作,则可以使用github.com/icza/bitio
库(公开:我是作者)。