• Base64编码原理


    Base64编码原理

    一、Base64的由来

    电子邮件刚问世的时候,只能传输英文,但后来随着用户的增加,中文、日文等文字的用户也有需求,但这些字符并不能被服务器或网关有效处理,为解决这一问题,最好的方案是在不改变传输协议的基础上,做一种扩展方案来支持非ASCII内容传输,把非 ASCII 字符用ASCII来表示,Base64编码应运而生。随之,Base64在URL、Cookie、网页传输少量二进制文件中也有相应的使用。

    二、什么是Base64?

    Base64 是一种编码方式,最早出现在电子邮件传输协议中。Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。

    三、Base64编码原理

    Base64 将8比特位为一个单元的字节数据拆分为以6个比特位为一个单元的二进制片段,不足6个比特位的在后面补0,在转为字符后补0的位置以=表示,2个0替换一个=号。每6个比特位单元对应Base64索引表中的一个字符,这样最终构成一个 超过编码前字节数据33% 的字符串。

    Base64索引图如下图所示:

    Base64索引表
    ASCII表如下图所示:

    img
    举个栗子:

    ABC三个字符进行base64编码,编码过程如下:

    文	本:		A					B					C
    ASCII码:	65					66					67
    8bit位:	 	01000001			01000010	 		01000011
    <-----------------------将8bit位化为6bit位----------------------->
    6bit位:		010000		010100		001001		000011
    Base64索引:	16			20			9			3
    Base64编码:	Q			U			J			D
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    8bit位:010000010100001001000011
    6bit位:010000010100001001000011
    3*8=24		24/6=4
    8bit位刚好能化为6bit位,不要补0.
    
    • 1
    • 2
    • 3
    • 4

    注意:
    ASCII码到 8bit位之间,是将ASCII转化位8位的二进制。6bit位到Base64索引之间,是将6位的二进制转化为十进制。

    abcd四个字符进行base64编码,编码过程如下:

    文	本:			a			b			c			d
    ASCII码:		97			98			99			100
    8bit位:	 	01100001	 01100010	 01100011	 01100100
    <----------------------将8bit位化为6bit位---------------------->
    6bit位:	   011000	010110	001001	100011	011001	000000
    Base64索引:	24		  22	  9		 35		  25	  0
    Base64编码:	Y		  W	 	  J		 j 		  Z		  A==
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    8bit位:01100001011000100110001101100100
    6bit位:011000010110001001100011011001000000
    4*8=32	32/6=5*6 + 2
    8bit位化为6bit位时,还差4位才能补齐最后的6位,因此在末尾补了4个0,当6bit位根据Base64索引表化为字符后需要在末尾补两个'==',一个'='代表补了两个0。
    
    • 1
    • 2
    • 3
    • 4

    四、通过Python实现Base64编码

    方案一:通过编码过程自己写Base64编码

    b64_dict = {
        0: 'A', 17: 'R', 34: 'i', 51: 'z',
        1: 'B', 18: 'S', 35: 'j', 52: '0',
        2: 'C', 19: 'T', 36: 'k', 53: '1',
        3: 'D', 20: 'U', 37: 'l', 54: '2',
        4: 'E', 21: 'V', 38: 'm', 55: '3',
        5: 'F', 22: 'W', 39: 'n', 56: '4',
        6: 'G', 23: 'X', 40: 'o', 57: '5',
        7: 'H', 24: 'Y', 41: 'p', 58: '6',
        8: 'I', 25: 'Z', 42: 'q', 59: '7',
        9: 'J', 26: 'a', 43: 'r', 60: '8',
        10: 'K', 27: 'b', 44: 's', 61: '9',
        11: 'L', 28: 'c', 45: 't', 62: '+',
        12: 'M', 29: 'd', 46: 'u', 63: '/',
        13: 'N', 30: 'e', 47: 'v',
        14: 'O', 31: 'f', 48: 'w',
        15: 'P', 32: 'g', 49: 'x',
        16: 'Q', 33: 'h', 50: 'y'}
    
    def b64_encode(str):   
        # 第一步:字符串转二进制,8bit位
        list64 = ''
        for c in str:
            print(ord(c))
            s = bin(ord(c))[2:]
            if len(s)%8 != 0:
                for i in range(8 - len(s)%8):
                    s = '0' + s
            list64 = list64 + s
    
        # 第二步:8bit位划分为6bit位,不足六位的补0
        if len(list64) % 6 == 0:
            for i in range(0, len(list64), 6):
                n6 = '0b' + list64[i:i + 6:1]
                num_0 = 0
        else:
            n = 6 - (len(list64) - (len(list64) // 6) * 6)
            for i in range(n):
                list64 = list64 + '0'
                num_0 = i + 1
    
        # 第三步:将6bit位化为十进制(Base64索引),放进myb64nums列表里
        myb64nums = []
        for i in range(0, len(list64), 6):
            n6 = list64[i:i + 6:1]
            myb64num = int(n6, 2)
            myb64nums.append(myb64num)
        print(myb64nums)
    
        # 第四步:通过Base64索引查询字符,并放进字符串中。
        b64_str=""
        for myb64num in myb64nums:
            b64_str=b64_str+b64_dict[myb64num]
            
        # 第五步:检测8bit化为6bit位时末尾是否补了0,如果补了则在字符后面补'='
        if num_0 != 0:
            for i in range(0, num_0 // 2):
                b64_str=b64_str+'='
        return b64_str
    
    print(b64_encode('abcd'))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    方案二:调用base64库实现base64编码

    import base64
    # base64加密
    b64_en = base64.b64encode('abcd'.encode())
    print(b64_en)
    
    #base64解密
    b64_de = base64.b64decode('YWJjZA=='.encode())
    print(b64_de)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
  • 相关阅读:
    Python基础知识从hello world 开始(第二天)
    Numpy入门[19]——结构化数组与记录数组
    4.1.9-映射应用程序体系结构
    OpenHarmony教程指南-自定义通知推送
    剑指 Offer 47. 礼物的最大价值 (百度一面 算法题)
    tooltip实现悬停内容染色
    【共读】企业信息安全建设与运维指南(二)
    Redis系列18:过期数据的删除策略
    Ubuntu18.04LTS安装配置VScode及下载C++相应第三方库
    表象变换与矩阵元
  • 原文地址:https://blog.csdn.net/weixin_49472648/article/details/126093351