Golang byte to int and []byte to int: strconv, binary, big.Int

Golang byte to int: uint8 widening, []byte ASCII to int with strconv.Atoi and validated ParseInt, math/big SetBytes for long unsigned magnitudes, encoding/binary Uint32 Uint64 and Read for int32, reverse int64 to []byte with PutUint64 and decimal FormatInt; endianness and errors.

Published

Updated

Read time 5 min read

Reviewed byDeepak Prasad

Golang byte to int and []byte to int: strconv, binary, big.Int

When you work with sockets, files, or protocols, you need to choose the right meaning of “bytes”: a single uint8, UTF-8 text digits for strconv, fixed-width wire integers for encoding/binary, or a long unsigned magnitude for math/big. The numbered examples below mirror the usual teaching order (ASCII first, then binary helpers, then reverses). For text bytes generally, see Go bytes to string. For broader math APIs, see Golang math.

Tested with Go 1.24 on Linux.


Single byte / uint8 to int (not []byte)

A byte is an alias for uint8. Widening to int is a conversion:

go
package main

import "fmt"

func main() {
	var b byte = 200
	var u uint8 = 255
	fmt.Println(int(b), int(u))
}
Output

You should see 200 and 255.


Example 1: Convert ASCII []byte to int

If the slice holds only decimal digits (and fits int range), strconv.Atoi is the shortest path. The argument must be valid UTF-8; ASCII digits are fine.

go
package main

import (
	"fmt"
	"strconv"
)

func main() {
	bs := []byte{'6', '6', '1'}
	n, err := strconv.Atoi(string(bs))
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(n)
}
Output

You should see 661.


Example 2: Convert ASCII []byte to an integer with validation

Atoi is convenient but does not let you cap bit width. Prefer strconv.ParseInt when you need a maximum size (for example values that must fit int32), want an explicit base, or must trim spaces and reject garbage.

go
package main

import (
	"fmt"
	"strconv"
	"strings"
)

func parseDecimalInt32(bs []byte) (int32, error) {
	s := strings.TrimSpace(string(bs))
	v, err := strconv.ParseInt(s, 10, 32)
	if err != nil {
		return 0, err
	}
	return int32(v), nil
}

func main() {
	for _, bs := range [][]byte{
		[]byte("  -42  "),
		[]byte("9999999999"), // overflows int32
		[]byte("12a"),
	} {
		v, err := parseDecimalInt32(bs)
		if err != nil {
			fmt.Printf("%q -> %v\n", string(bs), err)
			continue
		}
		fmt.Printf("%q -> %d\n", string(bs), v)
	}
}
Output

You should see -42 parse successfully, then strconv range or syntax errors for the bad rows.

For unsigned decimal text, use strconv.ParseUint with an appropriate bit size instead of ParseInt.


Example 3: Using math/big to convert []byte to an integer

Int.SetBytes interprets the slice as an unsigned big-endian integer of arbitrary length. It does not read a sign bit from the bytes; treat it as a magnitude.

go
package main

import (
	"fmt"
	"math/big"
)

func main() {
	bs := []byte{0x01, 0x00, 0x01}
	i := new(big.Int).SetBytes(bs)
	fmt.Println(i.String())
}
Output

You should see 65537.


Example 4: Using encoding/binary to convert a byte slice to int32 (or uint32)

When you already have exactly four bytes in wire order, you can decode without a bytes.Reader using Uint32 on the correct endianness, then cast if the protocol uses signed int32 with two’s-complement bits.

go
package main

import (
	"encoding/binary"
	"fmt"
)

func main() {
	raw := []byte{0x01, 0xFF, 0x01, 0xFF}
	if len(raw) < 4 {
		fmt.Println("too short")
		return
	}
	u := binary.BigEndian.Uint32(raw[:4])
	fmt.Println("as uint32:", u)
	fmt.Println("as int32:", int32(u))

	le := []byte{0x04, 0x03, 0x02, 0x01}
	fmt.Println("little-endian uint32:", binary.LittleEndian.Uint32(le[:4]))
}
Output

You should see 33489407 for the big-endian uint32, the same bit pattern reinterpreted as int32, and 16909060 for the little-endian example.

For eight-byte fields, use Uint64 and int64(binary.BigEndian.Uint64(buf)) when the wire format is signed two’s complement.

Variant: binary.Read for int32 from a stream

When bytes come from an io.Reader or you want the decoder to advance a cursor, binary.Read into a typed variable is convenient:

go
package main

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

func main() {
	var v int32
	raw := []byte{0x01, 0xFF, 0x01, 0xFF}
	r := bytes.NewReader(raw)
	if err := binary.Read(r, binary.BigEndian, &v); err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(v)
}
Output

You should see 33489407 as an int32 (same bits as the Uint32 example).


Example 5: Using encoding/binary to convert int64 to []byte (and back)

For signed int64 on the wire, the usual pattern is to cast to uint64 on write and cast back to int64 on read so two’s-complement layout is preserved.

go
package main

import (
	"encoding/binary"
	"fmt"
)

func main() {
	var x int64 = -1
	buf := make([]byte, 8)
	binary.BigEndian.PutUint64(buf, uint64(x))
	fmt.Println(buf)

	round := int64(binary.BigEndian.Uint64(buf))
	fmt.Println(round)
}
Output

You should see eight non-zero bytes for -1 in big-endian form, then -1 after the round trip.

Go 1.19+ also offers binary.Append to append a primitive to an existing []byte without pre-sizing manually.


Example 6: Decimal text int to []byte (reverse of Examples 1–2)

Use strconv.FormatInt (or FormatUint) and convert the string to bytes:

go
package main

import (
	"fmt"
	"strconv"
)

func main() {
	n := int64(33489407)
	ascii := strconv.FormatInt(n, 10)
	fmt.Println([]byte(ascii))
}
Output

You should see ASCII bytes for 33489407.


Summary

Pick the conversion that matches the data: int(b) for one byte; Examples 1–2 for decimal ASCII; Example 3 for long unsigned big-endian magnitudes; Examples 4–5 for fixed-width binary with explicit endianness and signed int64 casts when needed; Example 6 for human-readable decimal bytes. Always check lengths before slicing buf[:4] or buf[:8], and always handle strconv errors so 0 is not ambiguous.


References


Frequently Asked Questions

1. How do I convert a single golang byte to int?

Use a conversion: int(b) when b is a byte (alias of uint8); the value widens to int with the same numeric value 0 through 255.

2. How do I convert golang []byte to int from text digits?

If the slice holds ASCII decimal digits (and optional leading sign), use strconv.Atoi(string(bs)) or strconv.ParseInt with a bit size limit; always check the error and trim spaces if input can be padded.

3. How do I convert golang byte array to int from binary data?

Use encoding/binary: Uint32/Uint64 on a slice prefix for unsigned fixed widths, binary.Read into int32/int64 for signed fields, or math/big Int SetBytes for a variable-length unsigned big-endian magnitude.

4. Why does strconv.Atoi return 0 for bad input if I ignore the error?

Atoi returns (0, err) on failure; ignoring err makes 0 indistinguishable from a real zero; use ParseInt with explicit bit size or validate input first.

5. How do I golang convert int to byte or golang int to bytes?

Match your decode path: PutUint32/PutUint64 with the same endianness, big.Int.Bytes for unsigned big-endian magnitudes, or strconv.FormatInt for decimal ASCII bytes.

6. Does math/big SetBytes handle negative integers?

SetBytes treats the slice as an unsigned big-endian magnitude; for negative values use other constructors (for example SetString) or a signed binary layout with binary.Read into int64.
Tuan Nguyen

Data Scientist

Proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise …