Go Book / 2 Go Advances / 04 Go 数据编解码

04 Go 数据编解码

概述

在开发过程中我们经常会遇到数据传输的安全问题,这就需要一些加密算法的知识。加密算法大致分为三大类:一是编解码技术,二是哈希算法,三是基于密钥管理的加解密算法。 最简单的编解码技术是可逆的算法,一般用于数据格式化或加速传输的目的,安全较低。而哈希算法则叫做消息摘要,一般数据的传输校验,有正向计算快速,逆向困难的特点,通常没有巨大的算力是不可逆的。最后是基于密钥管理的对称加密和非对称加密,对称加密只有一个私钥,传输双方通过一个共有的私钥加解密,而非对称加密是由私钥以及由私钥产生的公钥共同管理,一般用于数字签名或数字证书。 三种算法的特点: 1.编解码算法:可逆,无需密钥。 2.哈希算法:生成摘要数据,不可逆; 3.加密解密算法:可逆,但是必须要有密钥;

Go 数据编解码

Go标准库提供了常用的编解码功能包:

  • encoding :定义了供其它包使用的可以将数据在字节水平和文本表示之间转换的接口。
  • encoding/ascii85:ascii85包实现了ascii85数据编码(5个ascii字符表示4个字节),该编码用于btoa工具和Adobe的PostScript语言和PDF文档格式。
  • encoding/asn1:实现了DER编码的ASN.1数据结构的解析
  • encoding/base32:实现了RFC 4648规定的base32编码。
  • encoding/base64:实现了RFC 4648规定的base64编码。
  • encoding/binary:实现了简单的数字与字节序列的转换以及变长值的编解码。
  • encoding/csv:实现了csv表格文件的编解码
  • encoding/gob :gob包管理gob流——在编码器(发送器)和解码器(接受器)之间交换的binary值。一般用于传递远端程序调用(RPC)的参数和结果,如net/rpc包就有提供。
  • encoding/hex:实现了16进制字符表示的编解码
  • encoding/json:实现了json对象的编解码
  • encoding/pem:实现了PEM数据编码(源自保密增强邮件协议)。目前PEM编码主要用于TLS密钥和证书。
  • encoding/xml:实现了xml对象的编解码

其作用是将go中的数据类型按一定的编码规范转换成其他数据格式,而转换目标又分为二进制格式和文本格式。我们在基础系列讲到的Json编解码就属于文本格式的编码类型,但在密码学中大多非加密的编解码都为二进制方式。

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,可用于在HTTP环境下传递较长的标识信息。Go 的 encoding/base64 提供了对base64的编解码操作。

encoding/base64 定义了一个Encoding结构体,表示Base64的编/解码器。并且导出了四个常用的Encoding对象:StdEncoding、URLEncoding、RawStdEncoding、RawURLEncoding。

  • StdEncoding表示标准的编/解码器。
  • URLEncoding用于对URL编解码,编解码过程中会将Base64编码中的特殊标记+和/替换为-和_。
  • RawStdEncoding和RawURLEncoding是StdEncoding和URLEncoding的非padding版本。

以下我们演示一下base64编解码的用例:

import (
 "encoding/base64"
 "fmt"
)
func BaseEncoding() {
    //1.标准的base64编解码
    //参与计算的输入必须为[]byte,这在go的数据传输中很常见。
    input := []byte("go func chan")
    
    // base64编码
    encodeString := base64.StdEncoding.EncodeToString(input)
    fmt.Println(encodeString)
    
    // base64解码
    if decodeBytes, err := base64.StdEncoding.DecodeString(encodeString); err != nil{
        fmt.Println("DecodeString Fail")
    }else{
        fmt.Println(string(decodeBytes))
    }
    
    
    //2.用于URL参数传输时的编解码,
    // 如果要用在url中,需要使用URLEncoding
    uEnc := base64.URLEncoding.EncodeToString([]byte(input))
    fmt.Println(uEnc)
    
    if uDec, err := base64.URLEncoding.DecodeString(uEnc);err != nil {
        fmt.Println("DecodeString Fail")
    }else{
        fmt.Println(string(uDec))
    }
    
}

以上演示了base64的编解码方式,其它用途的编解码包会在实战篇展开,接下来的密码学系列也会用到pem和hex的编解码。