GoLang 按位计算
GoLang bitwise calculation
我有一个缓冲区:
buffer := bytes.NewBuffer([]byte{
0x85, 0x02, 0xFF, 0xFF,
0x00, 0x01, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x03,
0x41, 0x42, 0x43,
})
我正在尝试 return 缓冲区的 int 值 [8:24]
我得到
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]
不确定如何移动这么大的部分。的字节。
新手。任何帮助都会很棒。我最初的方法是
requestid := (uint64(buffer.Bytes()[8]&0xff)<<24 + uint64(buffer.Bytes()[9]&0xff)<<16 + uint64(buffer.Bytes()[10]&0xff)<<8 + uint64(buffer.Bytes()[11]&0xff.....)))
但这很乏味,我知道必须有更简单的方法。
您必须手动进行移位和 OR'ing,但可以通过删除所有这些 buffer.Bytes()
调用来清理您的代码。
您也不需要 &0xff
部分。 n&0xff
所做的是清除 0-255
范围之外的所有位。由于缓冲区中的每个值已经是一个字节 (0-255),因此这些操作根本不执行任何操作。如果我们想做 22 & 255
,我们会得到以下结果:
Hexadecimal | Decimal | Binary
--------------|-------------|----------------------
x 0x16 | 22 | 00010110
y 0xff | 255 | 11111111
--------------|-------------|---------------------- AND (&)
0x16 | 22 | 00010110 = x
如您所见,操作完全没有效果。将 x
替换为任何 8 位值,您将看到相同的结果。 x & 0xff
的结果总是 x
.
此外,当您分配给 requestId
时,您首先要移动 24 位。这告诉我你正在读取一个 32 位整数。为什么还要继续读取超过 32 位的值并将其全部转换为 64 位整数?
如果您正在读取 Big Endian 中的 64 位 int,试试这个:
data := buf.Bytes()[8:]
requestid := uint64(data[0])<<56 | uint64(data[1])<<48 |
uint64(data[2])<<40 | uint64(data[3])<<32 |
uint64(data[4])<<24 | uint64(data[5])<<16 |
uint64(data[6])<<8 | uint64(data[7])
如果您正在 Little Endian 中读取 64 位 int,试试这个:
data := buf.Bytes()[8:]
requestid := uint64(data[7])<<56 | uint64(data[6])<<48 |
uint64(data[5])<<40 | uint64(data[4])<<32 |
uint64(data[3])<<24 | uint64(data[2])<<16 |
uint64(data[1])<<8 | uint64(data[0])
如果您正在读取 Big Endian 中的 32 位 int,试试这个:
data := buf.Bytes()[8:]
requestid := uint32(data[0])<<24 | uint32(data[1])<<16 |
uint32(data[2])<<8 | uint32(data[3])
如果您正在使用 Little Endian 读取 32 位 int,试试这个:
data := buf.Bytes()[8:]
requestid := uint32(data[3])<<24 | uint32(data[2])<<16 |
uint32(data[1])<<8 | uint32(data[0])
二进制包
或者,您可以使用 encoding/binary 包:
var value uint64
err := binary.Read(buf, binary.LittleEndian, &value)
....
我有一个缓冲区:
buffer := bytes.NewBuffer([]byte{
0x85, 0x02, 0xFF, 0xFF,
0x00, 0x01, 0x00, 0x02,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x03,
0x41, 0x42, 0x43,
})
我正在尝试 return 缓冲区的 int 值 [8:24] 我得到
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1]
不确定如何移动这么大的部分。的字节。
新手。任何帮助都会很棒。我最初的方法是
requestid := (uint64(buffer.Bytes()[8]&0xff)<<24 + uint64(buffer.Bytes()[9]&0xff)<<16 + uint64(buffer.Bytes()[10]&0xff)<<8 + uint64(buffer.Bytes()[11]&0xff.....)))
但这很乏味,我知道必须有更简单的方法。
您必须手动进行移位和 OR'ing,但可以通过删除所有这些 buffer.Bytes()
调用来清理您的代码。
您也不需要 &0xff
部分。 n&0xff
所做的是清除 0-255
范围之外的所有位。由于缓冲区中的每个值已经是一个字节 (0-255),因此这些操作根本不执行任何操作。如果我们想做 22 & 255
,我们会得到以下结果:
Hexadecimal | Decimal | Binary
--------------|-------------|----------------------
x 0x16 | 22 | 00010110
y 0xff | 255 | 11111111
--------------|-------------|---------------------- AND (&)
0x16 | 22 | 00010110 = x
如您所见,操作完全没有效果。将 x
替换为任何 8 位值,您将看到相同的结果。 x & 0xff
的结果总是 x
.
此外,当您分配给 requestId
时,您首先要移动 24 位。这告诉我你正在读取一个 32 位整数。为什么还要继续读取超过 32 位的值并将其全部转换为 64 位整数?
如果您正在读取 Big Endian 中的 64 位 int,试试这个:
data := buf.Bytes()[8:]
requestid := uint64(data[0])<<56 | uint64(data[1])<<48 |
uint64(data[2])<<40 | uint64(data[3])<<32 |
uint64(data[4])<<24 | uint64(data[5])<<16 |
uint64(data[6])<<8 | uint64(data[7])
如果您正在 Little Endian 中读取 64 位 int,试试这个:
data := buf.Bytes()[8:]
requestid := uint64(data[7])<<56 | uint64(data[6])<<48 |
uint64(data[5])<<40 | uint64(data[4])<<32 |
uint64(data[3])<<24 | uint64(data[2])<<16 |
uint64(data[1])<<8 | uint64(data[0])
如果您正在读取 Big Endian 中的 32 位 int,试试这个:
data := buf.Bytes()[8:]
requestid := uint32(data[0])<<24 | uint32(data[1])<<16 |
uint32(data[2])<<8 | uint32(data[3])
如果您正在使用 Little Endian 读取 32 位 int,试试这个:
data := buf.Bytes()[8:]
requestid := uint32(data[3])<<24 | uint32(data[2])<<16 |
uint32(data[1])<<8 | uint32(data[0])
二进制包
或者,您可以使用 encoding/binary 包:
var value uint64
err := binary.Read(buf, binary.LittleEndian, &value)
....