декодирование base64, затем декодирование json: base64.NewDecoder ошибка EOF и ошибка недопустимого символа json - PullRequest
0 голосов
/ 19 октября 2018

Я пытаюсь декодировать HTTP-запрос base64, а затем декодировать его с помощью JSON-декодера.

Я пытался реализовать декодер base64 двумя способами:

func decode(encoded []byte) ([]byte, error) {
    buff := new(bytes.Buffer)
    decoder := base64.NewDecoder(base64.StdEncoding, buff)
    _, err := decoder.Read(encoded)

    return buff.Bytes(), err
}

Эта функция возвращает ошибку EOF,Перейти на игровую площадку: https://play.golang.org/p/038rEXWYW6q


func decode(encoded []byte) ([]byte, error) {
    decoded := make([]byte, base64.StdEncoding.EncodedLen(len(encoded)))
    _, err := base64.StdEncoding.Decode(decoded, encoded)
    return decoded, err
}

Это работает, но имеет дополнительные x\00 символы, поэтому при декодировании JSON у нас будет ошибка invalid character '\x00' after top-level value.

В чем проблемас первой стратегией?

1 Ответ

0 голосов
/ 19 октября 2018

В вашем коде:

Вы создаете новый буфер и присваиваете ему buff, так как вы не указали источник ввода для него, он пуст.

buff := new(bytes.Buffer)

и NewDecoder читает с пустого buff.Как и все в процессе, если вы хотите создать что-то новое, вы должны использовать его конструктор, который всегда начинается с package.Newxxx

bytes.NewBuffer(src)

Тогда decoder - это переменная, которая содержит фактические декодированные данные, иимеет reader interface (метод чтения).Таким образом, вы можете передать его методу, который принимает reader interface, и ioutil.ReadAll() является одним из них.

Добавлены комментарии, когда это необходимо:

package main

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

// encoded data
var data = "eyJhY3Rpdml0aWVzIjpbXSwic3VjY2VzcyI6ZmFsc2UsImNvZGUiOjk5OTl9"

func main() {
    dec, err := decode([]byte(data))
    if err != nil {
        log.Println(err)
    }
    fmt.Println(string(dec)) // print returned value
}

func decode(enc []byte) ([]byte, error) {
    // create new buffer from enc
    // you can also use bytes.NewBuffer(enc)
    r := bytes.NewReader(enc)
    // pass it to NewDecoder so that it can read data
    dec := base64.NewDecoder(base64.StdEncoding, r)
    // read decoded data from dec to res
    res, err := ioutil.ReadAll(dec)
    return res, err
}

Infact все это может быть написанов одну строку:

func decode(enc []byte) ([]byte, error) {
    return ioutil.ReadAll(base64.NewDecoder(base64.StdEncoding, bytes.NewReader(enc)))
}

Вывод:

{"activities":[],"success":false,"code":9999}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...