The len prefix is superficial and causes the invalid utf-8 error:
package main
import (
"encoding/base64"
"fmt"
"log"
)
func main() {
str := base64.StdEncoding.EncodeToString([]byte("Hello, playground"))
fmt.Println(str)
data, err := base64.StdEncoding.DecodeString(str)
if err != nil {
log.Fatal("error:", err)
}
fmt.Printf("%q\n", data)
}
(Also here)
Output
SGVsbG8sIHBsYXlncm91bmQ=
"Hello, playground"
EDIT: I read too fast, the len was not used as a prefix. dystroy got it right.
Answer from zzzz on Stack Overflowgo - Encode/Decode base64 - Stack Overflow
Go auto decodes base64 encoded string while unmarshlling
Doing base64 decoding on a string in Go - Stack Overflow
google app engine - Base64 encode/decode without padding on golang ( appengine ) - Stack Overflow
The len prefix is superficial and causes the invalid utf-8 error:
package main
import (
"encoding/base64"
"fmt"
"log"
)
func main() {
str := base64.StdEncoding.EncodeToString([]byte("Hello, playground"))
fmt.Println(str)
data, err := base64.StdEncoding.DecodeString(str)
if err != nil {
log.Fatal("error:", err)
}
fmt.Printf("%q\n", data)
}
(Also here)
Output
SGVsbG8sIHBsYXlncm91bmQ=
"Hello, playground"
EDIT: I read too fast, the len was not used as a prefix. dystroy got it right.
DecodedLen returns the maximal length.
This length is useful for sizing your buffer but part of the buffer won't be written and thus won't be valid UTF-8.
You have to use only the real written length returned by the Decode function.
l, _ := base64.StdEncoding.Decode(base64Text, []byte(message))
log.Printf("base64: %s\n", base64Text[:l])
Go1.5 will have a WithPadding option on Encoding.
This also will add 2 pre-defined encodings, RawStdEncoding, and RawURLEncoding, which will have no padding.
Though since you're on app-engine, and won't have access to Go1.5 for a while, you can make some helper function to add and remove the padding as needed.
Here is an example to encode and decode strings. If you need, it could easily be adapted to work more efficiently using []byte.
func base64EncodeStripped(s string) string {
encoded := base64.StdEncoding.EncodeToString([]byte(s))
return strings.TrimRight(encoded, "=")
}
func base64DecodeStripped(s string) (string, error) {
if i := len(s) % 4; i != 0 {
s += strings.Repeat("=", 4-i)
}
decoded, err := base64.StdEncoding.DecodeString(s)
return string(decoded), err
}
Simply,
use base64.RawStdEncoding.EncodeToString instead of base64.StdEncoding.EncodeToString
OR else
use base64.RawURLEncoding.EncodeToString instead of base64.URLEncoding.EncodeToString.
Reference: see source-code comments Line 94 to 110:
// RawURLEncoding is the unpadded alternate base64 encoding defined in RFC 4648.
// It is typically used in URLs and file names.
// This is the same as URLEncoding but omits padding characters.