美文网首页
Base64 编解码

Base64 编解码

作者: 听海吹牛逼的声音 | 来源:发表于2019-02-21 15:14 被阅读0次

之前也遇到过base64的encoding,当时并不清楚为什么需要base64编码。今天花时间了解了一下。这个文章写的挺详细的:Base64编码原理与应用。所以我也不需要复述过多的东西。

简单总结:因为单纯的2进制是使用ascii码的,所以会存在部分字符不可见,在不可见的情况下,你存在文件,实实在在写进去,没有问题,但是在一些场景,就是需要将他们表示成可见字符,比如url,不然有的处理会把一些字符理解成控制的特殊标记从而造成错误。或者JSOM,XML里面就是不支持binary,所以就是需要base64的存在了。

那这个base64把3个byte就是24个bit,转成4个base64字符,每个代表6个bit。但是这四个字符是实实在在存成ascii的(可见),所以消耗存储长度是32bit。所以说base64编码多消耗了33%的存储空间。

看看go里面base64的编码。里面的NoPadding就是那个文章里说的要不要加=号。解码也是相似的位运算,但是因为需要考虑有没有padding,就需要有一些判断,但是思想一样。下面代码是编码过程,加了一些注释。

func TestBase64() {
    str := "hello"
    encoded := base64.StdEncoding.EncodeToString([]byte(str))
    fmt.Println(encoded)
    decoded, err := base64.StdEncoding.DecodeString(encoded)
    if err != nil {
        fmt.Println("decode error:", err)
        return
    }

    fmt.Println(string(decoded))
}

output:
aGVsbG8=
hello
func (enc *Encoding) EncodeToString(src []byte) string {
    buf := make([]byte, enc.EncodedLen(len(src)))
    enc.Encode(buf, src)
    return string(buf)
}
func (enc *Encoding) EncodedLen(n int) int {
    if enc.padChar == NoPadding {
        return (n*8 + 5) / 6 // minimum # chars at 6 bits per char
    }
    // 这个就是除三取上整,然后乘4,相当于把3个变成4个字符。所以就是3个一组的转换
    return (n + 2) / 3 * 4 // minimum # 4-char quanta, 3 bytes each
}

unc (enc *Encoding) Encode(dst, src []byte) {
    if len(src) == 0 {
        return
    }

    di, si := 0, 0
    n := (len(src) / 3) * 3
    for si < n {
        // Convert 3x 8bit source bytes into 4 bytes
  // 全部都是位运算,也很简单,用src字符串中的3个取或运算
        val := uint(src[si+0])<<16 | uint(src[si+1])<<8 | uint(src[si+2])
// 把24位分给四个,那个0x3F就是6个1,与运算就取出来最低6位。
        dst[di+0] = enc.encode[val>>18&0x3F]
        dst[di+1] = enc.encode[val>>12&0x3F]
        dst[di+2] = enc.encode[val>>6&0x3F]
        dst[di+3] = enc.encode[val&0x3F]

        si += 3
        di += 4
    }

    remain := len(src) - si
    if remain == 0 {
        return
    }
    // Add the remaining small block
//src字符串不够3整除的时候,结尾只能剩1或者2个,根据情况来追加即可。
    val := uint(src[si+0]) << 16
    if remain == 2 {
        val |= uint(src[si+1]) << 8
    }

    dst[di+0] = enc.encode[val>>18&0x3F]
    dst[di+1] = enc.encode[val>>12&0x3F]
//补等号
    switch remain {
    case 2:
        dst[di+2] = enc.encode[val>>6&0x3F]
        if enc.padChar != NoPadding {
            dst[di+3] = byte(enc.padChar)
        }
    case 1:
        if enc.padChar != NoPadding {
            dst[di+2] = byte(enc.padChar)
            dst[di+3] = byte(enc.padChar)
        }
    }
}

相关文章

  • 编码

    TextEncoder, TextDecoder(实验中的功能) base64 编解码 Base64编码作用:由于...

  • C语言实现base64编解码

    base64编解码 工作中经常会用到base64编解码, 有些开源库中也有实现, 但是如果再去看他们的怎么用有时候...

  • iOS7 base64编解码

    文档 使用 参考 使用Base64编解码NSData和NSString对象

  • base64

    Python内置的base64可以直接进行base64的编解码: 由于标准的Base64编码后可能出现字符+和/,...

  • 批处理下的Base64编解码

    文件版 命令:certutil /?,参考 批处理版Base64编码工具 BASE64编解码工具bse.exe 字...

  • Android-加密机制详解

    编解码 Base64编码算法 Base64编码算法是一种用64个字符(ABCDEFGHIJKLMNOPQRSTUV...

  • Base64编码简单总结

    1 Base64编码原理 随着iOS7正式版推出,Apple增加了使用Base64编解码的支持。Base64编码之...

  • base64图片和字符串编解码详细过程

    base64图片和字符串编解码详细过程 base64图片编码过程 1、读取图片路径 NSString *path...

  • 在线工具

    在线编码工具:• BASE64编解码工具:https://base64.supfree.net/[https://...

  • 如何用终端命令&iOS代码base64编解码?

    『导语』 在iOS开发中base64如何用xcode进行编解码?如何用终端进行编解码?我将用以下例子说明:(xco...

网友评论

      本文标题:Base64 编解码

      本文链接:https://www.haomeiwen.com/subject/ftvryqtx.html