Home >Backend Development >Golang >Why does Go's `json.Marshal` convert []byte to a base64 string, and how can I fix it?
When attempting to convert a byte slice ([]byte) to JSON format, developers often encounter unexpected string representations. This article delves into the reasons for this behavior and provides a solution for marshaling byte slices accurately.
Consider the following code snippet:
import ( "encoding/json" "fmt" "os" ) func main() { type ColorGroup struct { ByteSlice []byte SingleByte byte IntSlice []int } group := ColorGroup{ ByteSlice: []byte{0, 0, 0, 1, 2, 3}, SingleByte: 10, IntSlice: []int{0, 0, 0, 1, 2, 3}, } b, err := json.Marshal(group) if err != nil { fmt.Println("error:", err) } os.Stdout.Write(b) }
When executed, this code outputs:
{"ByteSlice":"AAAAAQID","SingleByte":10,"IntSlice":[0,0,0,1,2,3]}
Intriguing, the ByteSlice field, which should contain an array of bytes, has been rendered as "AAAAAQID".
The explanation lies in the documentation for the json package:
Array and slice values encode as JSON arrays, except that []byte encodes as a base64-encoded string, and a nil slice encodes as the null JSON object.
In this case, the ByteSlice field, an array of bytes, is not encoded as a JSON array but rather as a base64-encoded string.
To marshal []byte data to JSON as expected, it's necessary to decode the base64 representation. Here's an updated version of the code:
package main import ( "encoding/base64" "encoding/json" "fmt" "os" ) func main() { type ColorGroup struct { ByteSlice []byte SingleByte byte IntSlice []int } group := ColorGroup{ ByteSlice: []byte{0, 0, 0, 1, 2, 3}, SingleByte: 10, IntSlice: []int{0, 0, 0, 1, 2, 3}, } // Decode ByteSlice from base64 before marshaling decodedByteSlice, err := base64.StdEncoding.DecodeString(string(group.ByteSlice)) if err != nil { fmt.Println("error:", err) } group.ByteSlice = decodedByteSlice b, err := json.Marshal(group) if err != nil { fmt.Println("error:", err) } os.Stdout.Write(b) }
Now, the resulting JSON output correctly represents the ByteSlice field as an array of bytes:
{"ByteSlice":[0,0,0,1,2,3],"SingleByte":10,"IntSlice":[0,0,0,1,2,3]}
The above is the detailed content of Why does Go's `json.Marshal` convert []byte to a base64 string, and how can I fix it?. For more information, please follow other related articles on the PHP Chinese website!