zoukankan      html  css  js  c++  java
  • Golang---BASE64编码原理

    BASE64编码概念

      Base64 是一种基于64个可打印字符来表示二进制数据的表示方法。在 Base64中可打印字符包括字母 A-Z, a-z, 数字 0-9,这样共有 62 个字符,另外两个可打印符号在不同的编码系统中不同。由于 2^6 = 64, 所以每 6 个比特为一个单元,对应某个可打印字符。比如:3 个字节(ASCII 表示)有 24 个比特,可由 4 个 Base64 编码的可打印字符来表示。

    为什么要用 BASE64 编码

      BASE64编码会把 3 字节的二进制数据编码为 4 字节的文本数据,长度增加 33%,为什么我们还要用这种编码方式呢?好处就是编码后的文本数据可以在邮件正文、网页等直接显示。

    代码调用

      在 golang 中提供了两种格式的数据供我们直接调用,用于实现 BASE64 的编码和解码:

    // 来自 base64.go
    const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" const encodeURL = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"

      标准数据(encodeStr)可打印符号为:encodeStd 中的符号:

        msg := "Mac"
        base64URLEncoding := base64.StdEncoding.EncodeToString(([]byte(msg)))
        fmt.Println("Base64编码后:", base64URLEncoding)
        // 解码
        base64DecodeByte, err := base64.StdEncoding.DecodeString(base64URLEncoding)
        if err != nil {
            log.Panic(err)
        }
        fmt.Println("Base64解码后的字节数组:", base64DecodeByte)
        fmt.Println("Base64解码后:", string(base64DecodeByte))

    // 输出结果:

        Base64编码后: TWFj
        Base64解码后的字节数组: [77 97 99]
        Base64解码后: Mac

      URL数据(encodeURL) 可打印符号为:encodeURL 中的符号:

        msgUrl := "http://www.google.com"
        base64UrlEncodedString := base64.URLEncoding.EncodeToString([]byte(msgUrl))
        fmt.Println("Base64编码后:", base64UrlEncodedString)
        base64UrlDecodedByte, err := base64.URLEncoding.DecodeString(base64UrlEncodedString)
        if err != nil {
            log.Panic(err)
        }
        fmt.Println("Base64解码后的字节数组:", base64UrlDecodedByte)
        fmt.Println("Base64解码后:", string(base64UrlDecodedByte))

      // 输出结果

        Base64编码后: aHR0cDovL3d3dy5nb29nbGUuY29t
        Base64解码后的字节数组: [104 116 116 112 58 47 47 119 119 119 46 103 111 111 103 108 101 46 99 111 109]
        Base64解码后: http://www.google.com

    编码原理

    step1: 将每个字符转成 ASCII 编码

    msg := "Mac"
    fmt.Println([]byte(msg))  // [77 97 99]

    step2: 将 ASCII 转换成二进制编码

    msg := "Mac"
    fmt.Printf("%b
    ", []byte(msg))  // [1001101 1100001 1100011]

    补齐 8 位为:

    [01001101 01100001 01100011]

    step3: 将二进制编码按照 6位 一组进行平分

    010011 010110 000101 100011

    step4: 转换为十进制数:

    010011--->19
    010110--->22
    000101--->5
    100011--->35

    step5: 将转换的十进制数作为索引,从 Base64 编码表中查找字符

    索引              对应字符  
    0-->25          A---->Z
    26-->51         a----->z
    52-->61         0----->9
    62             "+" or  "-"
    63             "/" or "_"

    // 上面 "MAC" BASE64 编码结果为 TWFj
    19---> T
    22---> W
    5 ---> F
    35---> j

    注意

      BASE64 编码之后的结果总是 4 的整数倍,不够的需要在尾部补 “=” 符号

    若文本为 3个字符, 则刚好编码为 4个 字符长度(3 * 8 = 4 * 6)

    若文本为 2个字符, 则编码为 3个字符,尾部用一个 “=” 补齐

    若文本为 1 个字符,则编码为 2个字符,尾部用两个 “=” 补齐

     注:上表来自参考资料

    参考资料:

    https://blog.51cto.com/clovemfong/2160384

    http://loveshisong.cn/%E7%BC%96%E7%A8%8B%E6%8A%80%E6%9C%AF/2017-11-11-Base64%E4%B8%8EURLEncode%E7%AE%80%E4%BB%8B.html

  • 相关阅读:
    浅谈面向对象语言中对象的使用
    淘宝店铺搜索工具(提升淘宝店铺排名人气)
    JavaScript学习总结二:js闭包(Closure)概念
    JavaScript学习总结一:js常见问题
    GC原理解析(c#)
    VS2010中的测试(2)——单元测试
    VS2010中的测试(3)——数据驱动单元测试
    领域驱动设计实践(二)
    俞敏洪在清华励志演讲
    Ioc最佳实践
  • 原文地址:https://www.cnblogs.com/zpcoding/p/12000054.html
Copyright © 2011-2022 走看看