How to convert from []byte to int in Go Programming
Asked Answered
C

9

123

I need to create a client-server example over TCP. In the client side I read 2 numbers and I send them to the server. The problem I faced is that I can't convert from []byte to int, because the communication accept only data of type []byte.

Is there any way to convert []byte to int or I can send int to the server?

Some sample code will be really appreciated.

Thanks.

Celom answered 25/6, 2012 at 6:24 Comment(3)
Just to clarify the task, are you writing both the client and the server code? And are both written in Go?Lablab
AFAIK you have to do bit shift.Lawrence
To send data to the network it needs to be in byte form.Tingley
V
133

You can use encoding/binary's ByteOrder to do this for 16, 32, 64 bit types

Play

package main

import "fmt"
import "encoding/binary"

func main() {
    var mySlice = []byte{244, 244, 244, 244, 244, 244, 244, 244}
    data := binary.BigEndian.Uint64(mySlice)
    fmt.Println(data)
}
Voyeurism answered 25/10, 2014 at 11:37 Comment(5)
what do you mean by offsets? as in, reading from the middle of a []byte? just do BigEndian.Uint64(bigSlice[10:18]) (basically, read the bytes in the middle of the slice. or do you mean something else?Voyeurism
Ya, I figured after asking the stupid question. Just can't edit it :D Thanks though.Yea
It returns uint16, uint32, unit64 but not int. Need to convert to int from uintTyika
Sort of obvious, but not at first when just wanting to go byte[] to int: this does not work for a case where the byte array is very small. For one of my cases I have a byte array with only 2 elements, and the Uint64 method fails at this line in source _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808, since obviously the index is out of bounds. I needed the Uint16 method.Airmail
@TinkalGogoi use int64(value) to convert a value to an int64.Suwannee
T
23

If []byte is ASCII byte numbers then first convert the []byte to string and use the strconv package Atoi method which convert string to int.

package main
import (
    "fmt"
    "strconv"
)

func main() {
    byteNumber := []byte("14")
    byteToInt, _ := strconv.Atoi(string(byteNumber))
    fmt.Println(byteToInt)
}

Go playground

Tyika answered 21/3, 2019 at 10:53 Comment(2)
parsing an int to a string, then to a byte array and reverse looks like a too long wayDulia
Yes, a byte to int would be less expensive but haven't found a way.Tyika
F
13

Starting from a byte array you can use the binary package to do the conversions.

For example if you want to read ints :

buf := bytes.NewBuffer(b) // b is []byte
myfirstint, err := binary.ReadVarint(buf)
anotherint, err := binary.ReadVarint(buf)

The same package allows the reading of unsigned int or floats, with the desired byte orders, using the general Read function.

Focal answered 25/6, 2012 at 6:53 Comment(3)
Varint is specific for protocol buffers and is probably not what you're looking for. Spec: code.google.com/apis/protocolbuffers/docs/encoding.htmlLawrence
Just to clarify, a 32 bit integer may use up to 5 bytes after encoded by Varint.Lawrence
This doesn't work for the OP's use case. Use binary.Read() instead. See: codereview.stackexchange.com/questions/15945/…Tingley
S
10
now := []byte{0xFF,0xFF,0xFF,0xFF}
nowBuffer := bytes.NewReader(now)
var  nowVar uint32
binary.Read(nowBuffer,binary.BigEndian,&nowVar)
fmt.Println(nowVar)
4294967295
Schoolmaster answered 21/8, 2020 at 8:47 Comment(0)
L
9

The math/big provides a simple and easy way to convert a binary slice to a number playground

package main
import (
    "fmt"
    "math/big"
)
func main() {

    b := []byte{0x01, 0x00, 0x01}

    v := int(big.NewInt(0).SetBytes(b).Uint64())

    fmt.Printf("%v", v)
}
Levitan answered 7/3, 2022 at 13:19 Comment(0)
S
6

For encoding/decoding numbers to/from byte sequences, there's the encoding/binary package. There are examples in the documentation: see the Examples section in the table of contents.

These encoding functions operate on io.Writer interfaces. The net.TCPConn type implements io.Writer, so you can write/read directly to network connections.

If you've got a Go program on either side of the connection, you may want to look at using encoding/gob. See the article "Gobs of data" for a walkthrough of using gob (skip to the bottom to see a self-contained example).

Smite answered 25/6, 2012 at 7:0 Comment(2)
Can you give an example of how to use gob in a TCP application?Celom
I've added a link to an article that describes gobs; you can skip to the bottom if you just want to see a code example. When you construct an encoder/decoder, you can just pass in the *TCPConn as the argument to gob.NewEncoder/gob.NewDecoder.Smite
S
3

Using bitwise operator without additional dependencies

func toInt(bytes []byte) int {
    result := 0
    for i := 0; i < 4; i++ {
        result = result << 8
        result += int(bytes[i])

    }

    return result
}
Stamin answered 23/8, 2022 at 19:31 Comment(0)
L
2

If bytes in the []byte array are ASCII characters from 0 to 9 you can convert them to an int in a loop:

var value int
for _, b := range []byte{48, 49, 50, 51, 52} {
    value = value*10 + int(b-48)
}
fmt.Printf("integer value: %d", value)

Go Playground

Leix answered 18/12, 2022 at 14:52 Comment(0)
S
0

binary.Read in encoding/binary provides mechanisms to convert byte arrays to datatypes.

Note that Network Byte Order is BigEndian, so in this case, you'll want to specify binary.BigEndian.

  package main

  import (
    "bytes"
    "encoding/binary"
    "fmt"
  )

  func main() {
    var myInt int
    b := []byte{0x18, 0x2d} // This could also be a stream
    buf := bytes.NewReader(b)
    err := binary.Read(buf, binary.BigEndian, &myInt) // Make sure you know if the data is LittleEndian or BigEndian
    if err != nil {
        fmt.Println("binary.Read failed:", err)
        return
    }
    fmt.Print(myInt)
  }

Reviewing this documentation may be helpful: https://pkg.go.dev/encoding/[email protected]#Read

Schonthal answered 20/9, 2021 at 16:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.