HowtoGo
Home / Standard Library / encoding/base64
Standard Library

encoding/base64

encoding/base64 implements the base64 encoding from RFC 4648, turning arbitrary bytes into a compact, printable alphabet and back. Four ready-made Encoding values cover the standard, URL-safe, and unpadded variants.

EncodeToString and DecodeString on base64.StdEncoding are the two functions most code needs: bytes in, base64 text out, and back again.

msg := "Hello, 世界"
encoded := base64.StdEncoding.EncodeToString([]byte(msg))
fmt.Println(encoded)

decoded, err := base64.StdEncoding.DecodeString(encoded)
if err != nil {
    log.Fatal(err)
}
fmt.Println(string(decoded))

Every 3 raw bytes become 4 base64 characters, and the result is padded with = up to a multiple of 4 unless padding is explicitly turned off.

Terminal
$ go run main.go
SGVsbG8sIOS4lueVjA==
Hello, 世界

Try it

Examples

EncodedLen tells you how big the output buffer needs to be before a one-shot Encode call; EncodeToString skips that step for the common case.

data := []byte("go gopher")
fmt.Println(base64.StdEncoding.EncodedLen(len(data)))
fmt.Println(base64.StdEncoding.EncodeToString(data))
Output
12
Z28gZ29waGVy

Constants and package encodings

FunctionDescription
const StdPadding rune = '='
The default padding character used by StdEncoding and URLEncoding.
const NoPadding rune = -1
Passed to WithPadding to disable padding entirely.
var StdEncoding *Encoding
base64.StdEncoding.EncodeToString([]byte("hi")) // "aGk="
The standard base64 alphabet from RFC 4648, using + and /.
var URLEncoding *Encoding
The alternate RFC 4648 alphabet with - and _ in place of + and /, safe to drop directly into a URL or filename.
var RawStdEncoding *Encoding
StdEncoding with padding disabled: StdEncoding.WithPadding(NoPadding).
var RawURLEncoding *Encoding
URLEncoding with padding disabled: URLEncoding.WithPadding(NoPadding).

Building a custom Encoding

FunctionDescription
NewEncoding(encoder string) *Encoding
Builds a custom Encoding from a 64-byte alphabet string; the alphabet can't contain '=', '\r', or '\n', and must have no repeated bytes.
(Encoding) WithPadding(padding rune) *Encoding
Returns a copy of enc using a different padding character, or NoPadding to disable padding.
(Encoding) Strict() *Encoding
Returns a copy of enc that rejects input whose unused padding bits aren't zero, per RFC 4648 section 3.5.

Encoding

FunctionDescription
(*Encoding) EncodeToString(src []byte) string
base64.StdEncoding.EncodeToString([]byte("any + old & data"))
Returns the base64 encoding of src as a string, the usual entry point for encoding.
(*Encoding) Encode(dst, src []byte)
Writes EncodedLen(len(src)) bytes to dst, a caller-allocated buffer. Not meant for streaming individual blocks of a larger source; use NewEncoder for that.
(*Encoding) AppendEncode(dst, src []byte) []byte
Appends the encoding of src to dst and returns the grown slice, avoiding a separate allocation for the result.
(*Encoding) EncodedLen(n int) int
Returns how many bytes n bytes of input encode to, for sizing a destination buffer before calling Encode.

Decoding

FunctionDescription
(*Encoding) DecodeString(s string) ([]byte, error)
base64.StdEncoding.DecodeString("aGk=") // []byte("hi"), nil
Decodes a base64 string back to bytes, the usual entry point for decoding.
(*Encoding) Decode(dst, src []byte) (n int, err error)
Writes at most DecodedLen(len(src)) bytes to dst and returns how many were written; on malformed input it returns a CorruptInputError plus whatever decoded successfully.
(*Encoding) AppendDecode(dst, src []byte) ([]byte, error)
Appends the decoding of src to dst and returns the grown slice.
(*Encoding) DecodedLen(n int) int
Returns the maximum number of bytes n bytes of base64 could decode to, for sizing a destination buffer before calling Decode.

Streaming

FunctionDescription
NewEncoder(enc *Encoding, w io.Writer) io.WriteCloser
Wraps w so writes are base64-encoded before landing on the underlying writer; encoding happens in 4-byte blocks, so Close must be called to flush the final partial block.
NewDecoder(enc *Encoding, r io.Reader) io.Reader
Wraps r so reads come back base64-decoded; needs no Close since decoding never buffers a trailing partial block.

Errors

FunctionDescription
type CorruptInputError int64
Returned by Decode, DecodeString, and AppendDecode when the input isn't valid base64 for the encoding in use; the value is the byte offset of the bad input.
(CorruptInputError) Error() string
Formats the error with the offending byte offset.

Choosing an encoding

All four package-level encodings share the same underlying alphabet split between the standard and URL-safe variants; padding is the other independent choice, since either alphabet can be built with or without it.

// Four ready-made Encodings cover the common combinations:
base64.StdEncoding    // +  /  padded    - general purpose, MIME/PEM
base64.URLEncoding    // -  _  padded    - safe inside a URL path or filename
base64.RawStdEncoding // +  /  unpadded  - same alphabet, no trailing =
base64.RawURLEncoding // -  _  unpadded  - most common choice for tokens and IDs

A CorruptInputError is just an int64 byte offset under the hood, so unwrapping it with errors.As hands back exactly where decoding gave up.

// Decode reports a CorruptInputError instead of panicking on bad input.
_, err := base64.StdEncoding.DecodeString("not@valid!!")

var corruptErr base64.CorruptInputError
if errors.As(err, &corruptErr) {
    fmt.Println("bad byte at offset", int64(corruptErr))
}

The offset points at the first character outside the base64 alphabet, here the @ four characters in.

Terminal
$ go run main.go
bad byte at offset 3