简体   繁体   English

在go中将数组编码为base64

[英]Encode array to base64 in go

Here is my complete code for a function I develop: 这是我开发的函数的完整代码:

package main

import (
    "database/sql"
    "log"
    "encoding/xml"
    "github.com/gin-gonic/gin" //golang frameworks
    _ "github.com/go-sql-driver/mysql"
    "gopkg.in/gorp.v1"        //work with database(mysql, etc.)
)

type Genre struct {
    Title string `xml:"genre"`
}

type GenreArray struct {
    Auth_state int `xml:"auth_state"`
    Count int64 `xml:"count"`
    Item genreAPI `xml:"item"`
}

type UserPass struct {
    Username string `xml:"username"`
    Password string `xml:"password"`
}

type ErrorMessage struct {
    XMLName xml.Name `xml:"error"`
    Error string `xml:"error_code"`
    Message string `xml:"message"`
}

type Auth struct {
    XMLName xml.Name `xml:"config"`
    Nas_SharingEmpty  int `xml:"nas_sharing>auth_state"`
}

type ConfigGenre struct {
    XMLName xml.Name `xml:"config"`
    Nas_Sharing  GenreArray `xml:"nas_sharing"`
}

type genreAPI []Genre

var dbmap = initDb()

func initDb() *gorp.DbMap {

    db, err := sql.Open("mysql", "root@tcp(localhost:3306)/mymusic")
    checkErr(err, "sql.Open failed")
    dbmap := &gorp.DbMap{Db: db, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}

    return dbmap
}

func checkErr(err error, msg string) {
    if err != nil {
        log.Fatalln(msg, err)
    }
}

func main() {
    r := gin.Default()
    r.POST("/nas_sharing", myMusicXML)
    r.Run(":9999")
}

func myMusicXML(c *gin.Context) {

    c.Request.ParseForm()
    cmd := c.Request.Form.Get("cmd")
    usernamepost := c.Request.Form.Get("user")
    passwordpost := c.Request.Form.Get("passwd")

    if cmd == "36" {
    //Music Genre List API

        var genre []Genre
        var userpass []UserPass
        var count int64
        var countAuth int64

        //Query the post username and password
        _, errAuth := dbmap.Select(&userpass, "SELECT username, password FROM user WHERE username=? and password=?", usernamepost, passwordpost)

        //Check if post username and password exist
        countAuth, errAuth = dbmap.SelectInt("select count(*) FROM user WHERE username=? and password=?", usernamepost, passwordpost)
        if countAuth == 0 {
            //If no rows detected, output a message
            c.XML(404, Auth{Nas_SharingEmpty: 0})
        }else{
            //Check if query is valid
            if errAuth == nil {
                log.Println("auth_state :", countAuth)
            }else{
                c.XML(404, gin.H{"error": "sql query error found"})
            }

            //Query genre list
            _, err := dbmap.Select(&genre, "SELECT Title FROM genre_cntr_tbl")

            //Count genres
            count, err = dbmap.SelectInt("select count(*) FROM genre_cntr_tbl")
            if count == 0 {
                //If no rows detected, output a message
                c.XML(404, ErrorMessage{Error:"404", Message: "no genre found"})
            }else{
                //Check if query is valid
                if err == nil {
                    log.Println("Genres :", genre)
                    c.XML(200, ConfigGenre{Nas_Sharing: GenreArray{Auth_state: 1, Count: count, Item: genre,}})
                }else{
                    c.XML(404, gin.H{"error": "sql query error found"})
                }
            }
        }
    }else{
        c.XML(404, ErrorMessage{Error:"404", Message: "command not found"})
    }
}

And here is the output: 这是输出:

<config>
<nas_sharing>
    <auth_state>1</auth_state>
    <count>8</count>
    <item>
        <genre>Pop</genre>
    </item>
    <item>
        <genre>Rock</genre>
    </item>
    <item>
        <genre>Dance</genre>
    </item>
    <item>
        <genre>Opera</genre>
    </item>
    <item>
        <genre>Techno</genre>
    </item>
    <item>
        <genre>Hip Hop</genre>
    </item>
    <item>
        <genre>Jazz</genre>
    </item>
    <item>
        <genre>Reggae</genre>
    </item>
</nas_sharing>

Here is the value of genre of my output to log(note: It came from a database): 这是我输出到log的流派的值(注意:它来自数据库):

Genres : [{Pop} {Rock} {Dance} {Opera} {Techno} {Hiphop} {Jazz} {Reggae}]  

However, I would like to convert the output to base64 format. 但是,我想将输出转换为base64格式。 Here's a sample code for encoding to base64 but the data given to this is string unlike the one I develop that comes from an array. 这是一个用于编码为base64的示例代码,但是提供给它的数据是string ,这与我开发的来自数组的数据不同。 How could I achieve that output? 我如何实现该输出?

data := "/MyMusic/images/_albums/albums_nophoto.png"
sEnc := b64.StdEncoding.EncodeToString([]byte(data))
fmt.Println(sEnc)

Here is what output I expected 这是我期望的输出

<config>
<nas_sharing>
    <auth_state>1</auth_state>
    <count>8</count>
    <item>
        <genre>UG9w</genre>
    </item>
    <item>
        <genre>Um9jaw==</genre>
    </item>
    <item>
        <genre>RGFuY2U=</genre>
    </item>
    <item>
        <genre>T3BlcmE=</genre>
    </item>
    <item>
        <genre>VGVjaG5v</genre>
    </item>
    etc...

Foreword: The first section answers the original question (encode array to Base64). 前言:第一部分回答了原始问题(将数组编码为Base64)。 If you just want individual string fields to appear as Base64 strings in the output, see the 2nd section. 如果只希望单个string字段在输出中显示为Base64字符串,请参见第二部分。


Encoding a []string into Base64 format []string编码为Base64格式

Base64 is an encoding, a function used to convert an arbitrary sequence of bytes to a text using a small, well defined set of characters. Base64是一种编码,一种用于使用定义良好的小型字符集将任意字节序列转换为文本的功能。

So you have to decide / come up with a way to convert your []string array or slice to a sequence of bytes. 因此,您必须决定/想出一种方法来将[]string数组或切片转换为字节序列。

An easy and convenient way is to convert your []string to JSON text which will also take care of escaping strings having a quotation mark " for example. The result string can be easily encoded using the method you described: 一种简单方便的方法是将您的[]string转换为JSON文本,例如还将转义带有引号"字符串。转义结果string可以使用您描述的方法轻松进行编码:

genre := []string{"Pop", "Rock", "Dance", "Opera", "Techno", "Hiphop", "Jazz", "Reggae"}

data, _ := json.Marshal(&genre)
fmt.Println(string(data))
sEnc := base64.StdEncoding.EncodeToString(data)
fmt.Println(sEnc)

Output (try it on the Go Playground ): 输出(在Go Playground上尝试):

["Pop","Rock","Dance","Opera","Techno","Hiphop","Jazz","Reggae"]
WyJQb3AiLCJSb2NrIiwiRGFuY2UiLCJPcGVyYSIsIlRlY2hubyIsIkhpcGhvcCIsIkphenoiLCJSZWdnYWUiXQ==

Decoding 解码

Having such Base64 result, you can decode it like this: 有了这样的Base64结果,您可以像这样解码它:

data2, err := base64.StdEncoding.DecodeString(sEnc)
if err != nil {
    panic(err)
}
var genre2 []string
if err = json.Unmarshal(data2, &genre2); err != nil {
    panic(err)
}
fmt.Println(genre2)

Output: 输出:

[Pop Rock Dance Opera Techno Hiphop Jazz Reggae]

Notes: 笔记:

Of course you may choose any other transformations to convert []string to a byte sequence. 当然,您可以选择任何其他转换以将[]string转换为字节序列。 You could convert it to XML, or using the encoding/binary or anything else. 您可以将其转换为XML,或者使用encoding/binary或其他任何方式。 I chose JSON because it is a one-liner, compact, fast, and is supported in almost every programming language, so it won't be a problem if another program has to decode it. 我选择JSON是因为它是一种单行,紧凑,快速且几乎每种编程语言都支持的JSON,因此如果另一个程序必须对其进行解码将不会有问题。

Making individual string fields to appear as Base64 使单个string字段显示为Base64

You can do this by implementing the Marshaler interface on the type (or enclosing struct ) like this: 您可以通过在类型(或封闭struct )上实现Marshaler接口来实现此目的,如下所示:

func (g *Genre) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
    g2 := *g
    g2.Title = base64.StdEncoding.EncodeToString([]byte(g.Title))
    return e.EncodeElement(g2, start)
}

Basically what this does is creates a copy of Genre , changes the value of the Title field (of the copy) to the Base64 representation of its original value and encodes this copy. 基本上,这是创建Genre的副本,将(副本的)“ Title字段的值更改为其原始值的Base64表示,并对该副本进行编码。

Output (partial), try it on the Go Playground : 输出(部分),在Go Playground上尝试:

<GenreArray>
    <item>
        <genre>UG9w</genre>
    </item>
    <item>
        <genre>Um9jaw==</genre>
    </item>
</GenreArray>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM