Loading... ##什么是base64 <div class="tip inlineBlock share"> Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。可查看RFC2045~RFC2049,上面有MIME的详细规范。 Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。采用Base64编码具有不可读性,需要解码后才能阅读。 Base64由于以上优点被广泛应用于计算机的各个领域,然而由于输出内容中包括两个以上“符号类”字符(+, /, =),不同的应用场景又分别研制了Base64的各种“变种”。为统一和规范化Base64的输出,Base62x被视为无符号化的改进版本。[`Base64`][1] </div> **个人理解** base64就是将字符按`3`个字节进行分割,然后将二进制分为`6bit`一段,6bit最大表示数为64,所以形成base64。 字符串: abc ASCII:97 98 99 二进制: a => 0110 0001 b => 0110 0010 c => 0110 0011 组合起来是: 01100001 01100010 0110 0011 六位分段: 011000 010110 001001 100011 对应数字为: 24 22 9 35 base64表: Y W J k ![Base64编码表][2] ##代码 <div class="tab-container post_tab box-shadow-wrap-lg"> <ul class="nav no-padder b-b scroll-hide" role="tablist"> <li class='nav-item active' role="presentation"><a class='nav-link active' style="" data-toggle="tab" aria-controls='tabs-b5211caf64c43a9865c30cb444dae1bd260' role="tab" data-target='#tabs-b5211caf64c43a9865c30cb444dae1bd260'>原始方法</a></li><li class='nav-item ' role="presentation"><a class='nav-link ' style="" data-toggle="tab" aria-controls='tabs-a4963b4175cadc720a68da9eb9ac1f06821' role="tab" data-target='#tabs-a4963b4175cadc720a68da9eb9ac1f06821'>修改后方法</a></li> </ul> <div class="tab-content no-border"> <div role="tabpanel" id='tabs-b5211caf64c43a9865c30cb444dae1bd260' class="tab-pane fade active in"> def test(src): alphabet = b'ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxy0123456789+/' ret = bytearray() length = len(src) r = 0 for offset in range(0, length, 3): if offset + 3 <= length: triple = src[offset:offset + 3] else: triple = src[offset:] r = 3 - len(triple) triple = triple + '\x00' * r # '\x00' 就是ASCII对应的0 # abc = > 0x616263 # 大端模式 0x616263 => 61 62 63 => a b c b = int.from_bytes(triple.encode(), 'big') # 大端模式big,小端为little # from_bytes 将 byte 转为 int 类型 # b 0x616263 大端模式 # print(hex(b)) # b的状态为 01100001 01100010 01100011 # abc # 六位断开 011000 010110 001001 100011 for i in range(18, -1, -6): # 步进为-6 分别是 18 12 6 0 if i == 18: # 如果是18 b就移动18位 # 011000 010110 001001 100011 # 000000 000000 000000 011000 移位后的结果 只剩下最左边的那一段了 index = b >> i else: # i = 12 # 011000 010110 001001 100011 # 000000 000000 011000 010110 移位后结果 index = b >> i & 0x3F # & 位运算符,二进制同为1结果为1,否则为0 # 0x3F = 0b0011 1111 = 111111 #这里表示只保留最后六位 ret.append(alphabet[index]) for i in range(1, r + 1): ret[-i] = 0x3D return ret a = test(src='a') print(a) </div><div role="tabpanel" id='tabs-a4963b4175cadc720a68da9eb9ac1f06821' class="tab-pane fade "> def test(src): alphabet = b'ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklmnopqrstuvwxy0123456789+/' ret = bytearray() length = len(src) r = 0 for offset in range(0, length, 3): if offset + 3 <= length: triple = src[offset:offset + 3] else: triple = src[offset:] r = 3 - len(triple) triple = triple + '\x00' * r # '\x00' 就是ASCII对应的0 # abc = > 0x616263 # 大端模式 0x616263 => 61 62 63 => a b c b = int.from_bytes(triple.encode(), 'big') # 大端模式big,小端为little # from_bytes 将 byte 转为 int 类型 # b 0x616263 大端模式 # print(hex(b)) # b的状态为 01100001 01100010 01100011 # abc # 六位断开 011000 010110 001001 100011 for i in range(18, -1, -6): # 步进为-6 分别是 18 12 6 0 index = b >> i & 0x3F # 每次多做一次位与运算,当i为18的时候,位与运算不会影响结果 ret.append(alphabet[index]) for i in range(1, r + 1): ret[-i] = 0x3D return ret a = test(src='a') print(a) </div> </div> </div> [1]: https://baike.baidu.com/item/base64 [2]: https://blog.beijixs.cn/usr/uploads/2020/06/3816067347.jpg 最后修改:2020 年 06 月 18 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,请随意赞赏