package main
import (
"bytes"
"encoding/binary"
"fmt"
)
func main() {
aa := uint(0xFFFFFFFF)
fmt.Println(aa)
byteNewbuf := []byte{0xFF, 0xFF, 0xFF, 0xFF}
buf := bytes.NewBuffer(byteNewbuf)
tt, _ := binary.ReadUvarint(buf)
fmt.Println(tt)
}
Need to convert 4 bytes array to uint32 but why the results are not same ? go verion : beta 1.1
tt := uint32(buf[0])<<24 | uint32(buf[1])<<16 | uint32(buf[2]) <<8 |
uint32(buf[3])
for BE or
tt := uint32(buf[0]) | uint32(buf[1])<<8 | uint32(buf[2]) <<16 |
uint32(buf[3]) <<24
for LE.
[u]varint is a different kind of encoding (32 bit numbers can have as much as 5 bytes in the encoded form, 64 bit numbers up to 10).
No need to create a buffer for []byte. Use Varint or Uvarint directly on the byte slice instead.
You're throwing away the error returned by the function. The second result indicates how many bytes were read or if there was a problem. There is a problem while decoding 0xff, 0xff, 0xff, 0xff as an uvarint.
Here is how to use the encoding/binary package to do what you want. Note that you don't want to use any of the var
functions as those do variable length encoding.
package main
import (
"bytes"
"encoding/binary"
"fmt"
"log"
)
func main() {
aa := uint(0xFFFFFF0F)
fmt.Println(aa)
tt := uint32(0)
byteNewbuf := []byte{0x0F, 0xFF, 0xFF, 0xFF}
buf := bytes.NewBuffer(byteNewbuf)
err := binary.Read(buf, binary.LittleEndian, &tt)
if err != nil {
log.Fatalf("Decode failed: %s", err)
}
fmt.Println(tt)
}
Result is
4294967055
4294967055
byte alias for uint8
Since byte
is an alias for uint8
, your question, "Need to convert 4 bytes array to uint32", has already been answered:
How to convert [4]uint8 into uint32 in Go?
[Uvarints and] Varints are a method of encoding integers using one or more bytes; numbers with smaller absolute value take a smaller number of bytes. For a specification, see http://code.google.com/apis/protocolbuffers/docs/encoding.html.
Since Uvarint
s are a peculiar form of integer representation and storage, you should only use the ReadUvarint
function on values that have been written with the Uvarint
function.
For example,
package main
import (
"bytes"
"encoding/binary"
"fmt"
)
func main() {
buf := make([]byte, 10)
x := uint64(0xFFFFFFFF)
fmt.Printf("%2d %2d %v
", x, len(buf), buf)
n := binary.PutUvarint(buf, x)
buf = buf[:n]
fmt.Printf("%2d %2d %v
", x, len(buf), buf)
y, err := binary.ReadUvarint(bytes.NewBuffer(buf))
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("%2d %2d %v
", y, len(buf), buf)
}
Output:
4294967295 10 [0 0 0 0 0 0 0 0 0 0]
4294967295 5 [255 255 255 255 15]
4294967295 5 [255 255 255 255 15]
You can do this with one of the ByteOrder
objects from the encoding/binary
package. For instance:
package main
import (
"encoding/binary"
"fmt"
)
func main() {
aa := uint(0x7FFFFFFF)
fmt.Println(aa)
slice := []byte{0xFF, 0xFF, 0xFF, 0x7F}
tt := binary.LittleEndian.Uint32(slice)
fmt.Println(tt)
}
If your data is in big endian format, you can instead use the same methods on binary.BigEndian
.