有时候你需要将bytes编码非文本text.
最流行的编码是十六进制,其中每个字节由2个字符表示,而base64则将每个3个字节编码为4个字符。
Hex编码和解码
我们可以把[]byte编码为string,也可以把string解码为 []byte
d := []byte{0x01, 0xff, 0x3a, 0xcd}
s := hex.EncodeToString(d)
fmt.Printf("Hex: %s\n", s)
d2, err := hex.DecodeString(s)
if err != nil {
log.Fatalf("hex.DecodeString() failed with '%s'\n", err)
}
if !bytes.Equal(d, d2) {
log.Fatalf("decoded version is different than original")
}
Hex: 01ff3acd
使用fmt.Sprintf编码Hex
我们可以使用fmt.Sprintf和%x指令编码为字符串。 同样,我们可以使用fmt.Sscanf和%x进行解码。
指令%x除[] byte外还支持整数。
d := []byte{0x01, 0xff, 0x3a, 0xcd}
s := fmt.Sprintf("%x", d)
fmt.Printf("Hex: %s\n", s)
var decoded []byte
_, err := fmt.Sscanf(s, "%x", &decoded)
if err != nil {
log.Fatalf("fmt.Sscanf() failed with '%s'\n", err)
}
if !bytes.Equal(d, decoded) {
log.Fatalf("decoded version is different than original")
}
n := 3824
fmt.Printf("%d in hex is 0x%x\n", n, n)
Hex: 01ff3acd
3824 in hex is 0xef0
十六进制编码到writer,从reader解码
为了在流模式下对较大的值进行编码和解码,我们可以编码为io.Writer并从io.Reader进行解码。
d := []byte{0x01, 0xff, 0x3a, 0xcd}
writer := &bytes.Buffer{}
hexWriter := hex.NewEncoder(writer)
_, err := hexWriter.Write(d)
if err != nil {
log.Fatalf("hexWriter.Write() failed with '%s'\n", err)
}
encoded := writer.Bytes()
fmt.Printf("Hex: %s\n", string(encoded))
reader := bytes.NewBuffer(encoded)
hexReader := hex.NewDecoder(reader)
decoded, err := ioutil.ReadAll(hexReader)
if err != nil {
fmt.Printf("ioutil.ReadAll() failed with '%s'\n", err)
}
if !bytes.Equal(d, decoded) {
log.Fatalf("decoded version is different than original")
}
Hex: 01ff3acd
Base64编码和解码
使用base64也可以编码[]byte
d := []byte{0x01, 0xff, 0x3a, 0xcd}
s := base64.StdEncoding.EncodeToString(d)
fmt.Printf("base64: %s\n", s)
d2, err := base64.StdEncoding.DecodeString(s)
if err != nil {
log.Fatalf("hex.DecodeString() failed with '%s'\n", err)
}
if !bytes.Equal(d, d2) {
log.Fatalf("decoded version is different than original")
}
base64: Af86zQ==
URL-safe base64
不幸的是,原始的base64编码可能会产生在URL中无效的字符。
考虑到网址在当时很重要,因此我们提供了一种base64编码的变体,它没有该缺陷:
d := []byte{0x01, 0xff, 0x3a, 0xcd}
s := base64.URLEncoding.EncodeToString(d)
fmt.Printf("base64: %s\n", s)
d2, err := base64.URLEncoding.DecodeString(s)
if err != nil {
log.Fatalf("hex.DecodeString() failed with '%s'\n", err)
}
if !bytes.Equal(d, d2) {
log.Fatalf("decoded version is different than original")
}
base64: Af86zQ==
Base64编码到写入器,从读取器解码
为了在流模式下对较大的值进行编码和解码,我们可以编码为io.Writer并从io.Reader进行解码。
d := []byte{0x01, 0xff, 0x3a, 0xcd}
writer := &bytes.Buffer{}
base64Writer := base64.NewEncoder(base64.StdEncoding, writer)
_, err := base64Writer.Write(d)
if err != nil {
log.Fatalf("base64Writer.Write() failed with '%s'\n", err)
}
err = base64Writer.Close()
if err != nil {
log.Fatalf("base64Writer.Close() failed with '%s'\n", err)
}
encoded := writer.Bytes()
fmt.Printf("Base64: %s\n", string(encoded))
reader := bytes.NewBuffer(encoded)
base64Reader := base64.NewDecoder(base64.StdEncoding, reader)
decoded, err := ioutil.ReadAll(base64Reader)
if err != nil {
fmt.Printf("ioutil.ReadAll() failed with '%s'\n", err)
}
if !bytes.Equal(d, decoded) {
log.Fatalf("decoded version is different than original")
}
Base64: Af86zQ==