One byte is lost when encoding a file into base64 in Golang

Issue

package main

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

func b(name string) {
    f, err := os.Open(name)
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()

    buf := new(bytes.Buffer)
    binval := base64.NewEncoder(base64.StdEncoding, buf)
    if _, err := io.Copy(binval, f); err != nil {
        log.Fatal(err)
    }

    fmt.Printf("%s\n", buf.String()[buf.Len()-5:])
}

func main() {
    b("soccer.jpg")
    b("soccer2.jpg")
}

soccer.jpg
soccer2.jpg

Output:

bodqhrohro@debian:/tmp$ go run base64.go 
nuNf/
nuNf/

The first file is identical to the second one just with the last byte cut out. They yield an identical base64 string. What’s wrong?

I experience it with go1.15.9 and go1.18.3.

Solution

From the base64.NewEncoder docs:

the caller must Close the returned encoder to flush any partially written blocks.

So:

binval.Close() // add this

fmt.Printf("%s\n", buf.String()[buf.Len()-5:])

Answered By – colm.anseo

Answer Checked By – Candace Johnson (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.