ZetCode

Go Base64

Last modified: July 16, 2026

This Go Base64 tutorial shows how to encode and decode binary data to and from Base64 in Go using the encoding/base64 package. We cover standard encoding, URL-safe encoding, raw encodings, stream encoding, and image encoding.

Base64

Base64 is a binary-to-text encoding scheme that represents binary data in an ASCII string format by translating it into a radix-64 representation. It is defined in RFC 4648. Each Base64 digit represents exactly six bits of data, so three bytes (24 bits) can be represented using four Base64 characters.

Base64 encoding schemes are commonly used when we need to store and transfer binary data over media that are designed to deal with text. Common use cases include embedding images in HTML and CSS files, encoding email attachments via MIME, storing binary data in JSON or XML, and transmitting credentials in HTTP headers (Basic authentication).

In Go, we use the encoding/base64 package for Base64 encoding and decoding. It implements the base encoding specified by RFC 4648.

The following is the Base64 alphabet as defined by RFC 4648. Each character represents a six-bit value, ranging from 0 to 63.

Value Encoding  Value Encoding  Value Encoding  Value Encoding
 0 A            17 R            34 i            51 z
 1 B            18 S            35 j            52 0
 2 C            19 T            36 k            53 1
 3 D            20 U            37 l            54 2
 4 E            21 V            38 m            55 3
 5 F            22 W            39 n            56 4
 6 G            23 X            40 o            57 5
 7 H            24 Y            41 p            58 6
 8 I            25 Z            42 q            59 7
 9 J            26 a            43 r            60 8
10 K            27 b            44 s            61 9
11 L            28 c            45 t            62 +
12 M            29 d            46 u            63 /
13 N            30 e            47 v
14 O            31 f            48 w          (pad) =
15 P            32 g            49 x
16 Q            33 h            50 y

Go's encoding/base64 package provides four encoding variants to accommodate different use cases. The table below summarises each variant's characteristics.

Encoding Description
base64.StdEncoding Standard Base64 encoding with padding (=).
base64.URLEncoding URL-safe encoding. Replaces + and / with - and _. Includes padding.
base64.RawStdEncoding Standard encoding without padding.
base64.RawURLEncoding URL-safe encoding without padding.

The StdEncoding and URLEncoding variants append padding characters (=) to make the output length a multiple of four. The RawStdEncoding and RawURLEncoding variants omit padding, which is acceptable when the length is known or padding is unnecessary.

Encode with StdEncoding

The base64.StdEncoding.Encode function encodes a source slice of bytes into a destination slice of bytes using the standard Base64 alphabet.

func (*base64.Encoding).Encode(dst []byte, src []byte)

The destination is the first parameter, the source is the second.

main.go
package main

import (
    "encoding/base64"
    "fmt"
)

func main() {

    msg := "one 🐘 and three 🐋"
    fmt.Println(msg)

    data := make([]byte, base64.StdEncoding.EncodedLen(len(msg)))
    base64.StdEncoding.Encode(data, []byte(msg))

    fmt.Println(data)
    encoded := string(data)
    fmt.Println(encoded)
}

The program encodes a string containing emoji characters to Base64.

msg := "one 🐘 and three 🐋"

We have a string with two emojis.

data := make([]byte, base64.StdEncoding.EncodedLen(len(msg)))

The EncodedLen function returns the length in bytes of the Base64 encoding of an input buffer, so we can pre-allocate the destination slice.

base64.StdEncoding.Encode(data, []byte(msg))

We encode the data with base64.StdEncoding.Encode. The encoded bytes are written to the pre-allocated data slice.

$ go run main.go
one 🐘 and three 🐋
[98 50 53 108 73 80 67 102 107 74 103 103 89 87 53 ... 115 61]
b25lIPCfkJggYW5kIHRocmVlIPCfkIs=

Decode with StdEncoding

The base64.StdEncoding.Decode function decodes a Base64-encoded source slice of bytes into a destination slice of bytes.

main.go
package main

import (
    "encoding/base64"
    "fmt"
    "log"
)

func main() {

    encoded := "b25lIPCfkJggYW5kIHRocmVlIPCfkIs="
    fmt.Println(encoded)

    data := make([]byte, base64.StdEncoding.DecodedLen(len(encoded)))
    n, err := base64.StdEncoding.Decode(data, []byte(encoded))

    fmt.Println(data)

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(string(data[:n]))
}

The program decodes a Base64-encoded string back to its original form.

encoded := "b25lIPCfkJggYW5kIHRocmVlIPCfkIs="

This is the Base64-encoded string from the previous example.

data := make([]byte, base64.StdEncoding.DecodedLen(len(encoded)))

We pre-allocate a destination buffer using DecodedLen, which returns the maximum decoded length.

n, err := base64.StdEncoding.Decode(data, []byte(encoded))

The data is decoded. The function returns the number of bytes written and any decoding error.

$ go run main.go
b25lIPCfkJggYW5kIHRocmVlIPCfkIs=
[111 110 101 32 240 159 144 152 32 97 110 100 ... 240 159 144 139 0]
one 🐘 and three 🐋

Encode and decode strings

The EncodeToString and DecodeString convenience functions handle Base64 encoding and decoding directly with string types.

main.go
package main

import (
    "encoding/base64"
    "fmt"
    "log"
)

func main() {

    msg := "one 🐘 and three 🐋"

    fmt.Println(msg)

    str := base64.StdEncoding.EncodeToString([]byte(msg))
    fmt.Println(str)

    data, err := base64.StdEncoding.DecodeString(str)

    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(data)
    fmt.Println(string(data))
}

The program encodes a string to Base64 and decodes it back using the convenience functions.

$ go run main.go
one 🐘 and three 🐋
b25lIPCfkJggYW5kIHRocmVlIPCfkIs=
[111 110 101 32 240 159 144 152 32 ... 32 240 159 144 139]
one 🐘 and three 🐋

URL-safe encoding

The standard Base64 alphabet includes + and / characters, which have special meaning in URL path segments and query strings. The URL-safe encoding replaces these with - and _ respectively.

main.go
package main

import (
    "encoding/base64"
    "fmt"
)

func main() {

    msg := "<<Hello>>"

    std := base64.StdEncoding.EncodeToString([]byte(msg))
    fmt.Println("StdEncoding:", std)

    url := base64.URLEncoding.EncodeToString([]byte(msg))
    fmt.Println("URLEncoding:", url)

    data, _ := base64.URLEncoding.DecodeString(url)
    fmt.Println("Decoded:", string(data))
}

We encode the string <<Hello>> with both standard and URL-safe encoders. The < and > characters produce bytes that map to + and / in standard Base64, which are replaced with - and _ in URL-safe encoding.

$ go run main.go
StdEncoding: PDxIZWxsbz4+
URLEncoding: PDxIZWxsbz4-
Decoded: <<Hello>>

The standard encoding produces PDxIZWxsbz4+, which contains a + — a / would appear with different input. The URL-safe encoding produces PDxIZWxsbz4-, replacing + with -. Both decode correctly to the original string.

Raw encoding without padding

The RawStdEncoding and RawURLEncoding variants omit the trailing padding characters (=). This is useful when the encoded data length is known or padding is not required.

main.go
package main

import (
    "encoding/base64"
    "fmt"
)

func main() {

    msg := "Hello there!"

    std := base64.StdEncoding.EncodeToString([]byte(msg))
    raw := base64.RawStdEncoding.EncodeToString([]byte(msg))

    fmt.Println("StdEncoding:", std)
    fmt.Println("RawStdEncoding:", raw)
}

We compare the output of StdEncoding (with padding) and RawStdEncoding (without padding).

$ go run main.go
StdEncoding: SGVsbG8gdGhlcmUh
RawStdEncoding: SGVsbG8gdGhlcmUh

The RawStdEncoding output omits the == padding suffix. Both variants decode to the same original data.

Stream encoding

The base64.NewEncoder function creates a write stream that encodes data on the fly. This is efficient for large data sets that should not be held entirely in memory.

main.go
package main

import (
    "bytes"
    "encoding/base64"
    "fmt"
    "io"
)

func main() {

    msg := []byte("one 🐘 and three 🐋")

    var buf bytes.Buffer
    encoder := base64.NewEncoder(base64.StdEncoding, &buf)
    encoder.Write(msg)
    encoder.Close()

    fmt.Println(buf.String())

    decoder := base64.NewDecoder(base64.StdEncoding, &buf)
    decoded, _ := io.ReadAll(decoder)

    fmt.Println(string(decoded))
}

The example uses NewEncoder and NewDecoder to encode and decode data through streaming I/O.

encoder := base64.NewEncoder(base64.StdEncoding, &buf)

NewEncoder wraps a writer and returns an io.WriteCloser that encodes any data written to it.

decoder := base64.NewDecoder(base64.StdEncoding, &buf)

NewDecoder wraps a reader and returns an io.Reader that decodes data as it is read.

$ go run main.go
b25lIPCfkJggYW5kIHRocmVlIPCfkIs=
one 🐘 and three 🐋

Encoding images

A common practical use of Base64 is embedding binary image data directly into HTML or CSS files. The following example reads an image file and encodes it.

main.go
package main

import (
    "encoding/base64"
    "fmt"
    "os"
)

func main() {

    data, err := os.ReadFile("image.png")
    if err != nil {
        fmt.Println(err)
        return
    }

    encoded := base64.StdEncoding.EncodeToString(data)

    fmt.Println("data:image/png;base64," + encoded)
}

The example reads a PNG image into a byte slice and encodes it with Base64, producing a data URI suitable for embedding in an <img> tag.

data, err := os.ReadFile("image.png")

os.ReadFile reads the entire image file into a byte slice.

fmt.Println("data:image/png;base64," + encoded)

The encoded data is prefixed with the data URI scheme, which browsers recognize and can render directly.

Source

Go encoding/base64 package - reference

In this article we have worked with Base64 encoding in Go.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Go tutorials.