Home > Backend Development > Golang > Why does Go's `json.Marshal` convert []byte to a base64 string, and how can I fix it?

Why does Go's `json.Marshal` convert []byte to a base64 string, and how can I fix it?

Linda Hamilton
Release: 2024-12-22 00:04:17
Original
684 people have browsed it

Why does Go's `json.Marshal` convert []byte to a base64 string, and how can I fix it?

Marshaling []byte to JSON: Decoding Mysterious Strings

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.

The Puzzling Case

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)
}
Copy after login

When executed, this code outputs:

{"ByteSlice":"AAAAAQID","SingleByte":10,"IntSlice":[0,0,0,1,2,3]}
Copy after login

Intriguing, the ByteSlice field, which should contain an array of bytes, has been rendered as "AAAAAQID".

Unraveling the Mystery

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.

A Solution: Base64 Decoding

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)
}
Copy after login

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]}
Copy after login

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!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template