【JS逆向】【14.编码算法】Python 中 base64库编码(详细笔记)

Base64

1. base64是什么

Base64编码 是一种基于 64 个可打印字符来表示二进制数据的方法。目前 Base64 已经成为网络上常见的传输 8 位二进制字节代码的编码方式之一

Base64编码,是由64个字符组成编码集:26个大写字母AZ,26个小写字母az,10个数字0~9,符号“+”与符号“/”。Base64编码的基本思路是将原始数据的三个字节拆分转化为四个字节,然后根据Base64的对应表,得到对应的编码数据。

为什么会有 Base64 编码呢?因为有些网络传送渠道并不支持所有的字节,例如:传统的邮件只支持可见字符的传送,像 ASCII 码的控制字符就不能通过邮件传送。这样用途就受到了很大的限制。

图片的二进制流的每个字节不可能全部是可见字符,这就导致图片的二进制流无法传送。最好的解决方式就是在不改变传统协议的情况下,做一种扩展方案来支持二进制文件的传送。即把不可打印的字符也能用可打印字符来表示,问题就解决了

2. base64原理

在这里插入图片描述
一个Base64字符实际上代表着6个二进制位(bit),4个Base64字符对应3字节字符串/二进制数据。

3个字符为一组的的base64编码方式如:

在这里插入图片描述

import base64

# base64的实现细节
# 3位数
data = "you" # 3个字符 8 个 bit = 24 / 6  = 编码后4个字符
print(base64.b64encode(data.encode()).decode())  # eW91
print(ord("y"))  # ASCLL码:121
print(ord("o"))  # ASCLL码:111
print(ord("u"))  # ASCLL码:117
print(bin(121))  # 二进制 : 01111001
print(bin(111))  # 二进制 : 01101111
print(bin(117))  # 二进制 : 01110101
print(ord("a"))  # 97

小于3个字符为一组的编码方式如:
在这里插入图片描述

# 2位数
data1 = "yo"
print(base64.b64encode(data1.encode()).decode())  # eW8=
print(bin(121))  # 二进制 : 01111001
print(bin(111))  # 二进制 : 01101111

总结:base64过程
在这里插入图片描述

3. 测试 base64

import base64

# 案例1
# base64编码
data = "i love you!"
ret = base64.b64encode(data.encode()).decode()
print(ret)  # aSBsb3ZlIHlvdSE=

# base64解码
s = "aSBsb3ZlIHlvdSE="
ret = base64.b64decode(s).decode()
print(ret)  # i love you

注意:b64处理后的字符串长度. 一定是4的倍数. 如果在网页上看到有些密文的b64长度不是4的倍数. 会报错

import base64

s = "eW91"  # 4位
ret = base64.b64decode(s)
print(ret)  # b'you'

s = "eW91eQ=="  # 8位
ret = base64.b64decode(s)
print(ret)  # b'youy'

s = "eW91eQ"  # 6位,少了2位所以会报错
ret = base64.b64decode(s)
print(ret)  # 报错

# 案例2:数据填充:base64解码的数据一定要是4的倍数,不然解码会报错
s = "aSBsb3ZlIHlvdSE"
# 手动补充
s += "=" * (4 - len(s) % 4)
print(s)  # aSBsb3ZlIHlvdSE=
ret = base64.b64decode(s).decode()
print(ret)  # i love you!

4. base64变种

在这里插入图片描述

import base64

# 案例3:base64的变种
data = "BkiKG8jzVGzbWOl4m8NXJEYglgtxhOB05MGmap8JSP97GzoewPBmDTs7c5iACUof3k/uJf0H88GygajVgBvkcbckJp7oO+Qj6VSUQYTOHhKN/VG2a8v+WzL34EO/S7BYoj2oOxIDAr8wDLxYxjBeXq/Be6Q1yBbnZcKaMkifhP8="
new_data = data.replace("+", "-").replace("/", "_")
print(new_data)
# BkiKG8jzVGzbWOl4m8NXJEYglgtxhOB05MGmap8JSP97GzoewPBmDTs7c5iACUof3k_uJf0H88GygajVgBvkcbckJp7oO-Qj6VSUQYTOHhKN_VG2a8v-WzL34EO_S7BYoj2oOxIDAr8wDLxYxjBeXq_Be6Q1yBbnZcKaMkifhP8=

new_data = "BkiKG8jzVGzbWOl4m8NXJEYglgtxhOB05MGmap8JSP97GzoewPBmDTs7c5iACUof3k_uJf0H88GygajVgBvkcbckJp7oO-Qj6VSUQYTOHhKN_VG2a8v-WzL34EO_S7BYoj2oOxIDAr8wDLxYxjBeXq_Be6Q1yBbnZcKaMkifhP8="
data = new_data.replace("-", "+").replace("_", "/")
print(data)
# BkiKG8jzVGzbWOl4m8NXJEYglgtxhOB05MGmap8JSP97GzoewPBmDTs7c5iACUof3k/uJf0H88GygajVgBvkcbckJp7oO+Qj6VSUQYTOHhKN/VG2a8v+WzL34EO/S7BYoj2oOxIDAr8wDLxYxjBeXq/Be6Q1yBbnZcKaMkifhP8=
print(base64.b64decode(data))
# b'\x06H\x8a\x1b\xc8\xf3Tl\xdbX\xe9x\x9b\xc3W$F \x96\x0bq\x84\xe0t\xe4\xc1\xa6j\x9f\tH\xff{\x1b:\x1e\xc0\xf0f\r;;s\x98\x80\tJ\x1f\xdeO\xee%\xfd\x07\xf3\xc1\xb2\x81\xa8\xd5\x80\x1b\xe4q\xb7$&\x9e\xe8;\xe4#\xe9T\x94A\x84\xce\x1e\x12\x8d\xfdQ\xb6k\xcb\xfe[2\xf7\xe0C\xbfK\xb0X\xa2=\xa8;\x12\x03\x02\xbf0\x0c\xbcX\xc60^^\xaf\xc1{\xa45\xc8\x16\xe7e\xc2\x9a2H\x9f\x84\xff'

5. 为什么要base64编码

base64 编码的优点:

  • 算法是编码,不是压缩,编码后只会增加字节数(一般是比之前的多1/3,比如之前是3, 编码后是4)
  • 算法简单,基本不影响效率
  • 算法可逆,解码很方便,不用于私密传输。
  • 加密后的字符串只有【0-9a-zA-Z+/=】 ,不可打印字符(转译字符)也可以传输(关键!!!)

有些网络传输协议是为了传输ASCII文本设计的,当你使用其传输二进制流时(比如视频/图片),二进制流中的数据可能会被协议错误的识别为控制字符等等,因而出现错误。那这时就要将二进制流传输编码,因为有些8Bit字节码并没有对应的ASCII字符。

比如十进制ASCII码8对应的是后退符号(backspace), 如果被编码的数据中包含这个数值,那么编码出来的结果在很多编程语言里会导致前一个字符被删掉。又比如ASCII码0对应的是空字符,在一些编程语言里代表字符串结束,后续的数据就不会被处理了。

用Base64编码因为限定了用于编码的字符集,确保编码的结果可打印且无歧义。

不同的网络节点设备交互数据需要:设备A把base64编码后的数据封装在json字符串里,设备B先解析json拿到value,再进行base64解码拿到想要的数据。

  1. 早年制定的一些协议都是只支持文本设定的。随着不断发展需要支持非文本了,才搞了一个base64做兼容
  2. 虽然编码之后的数据与加密一样都具有不可见性,但编码与加密的概念并不一样。编码是公开的,任何人都可以解码;而加密则相反,你只希望自己或者特定的人才可以对内容进行解密。

base64处理图片数据:

import base64

source = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAA7VBMVEUAAADs8v+txP+qwv+4zf/w9f/2+P+hu//Q3f+yyP+4zf/Q3f+kvv+90P+80f+2yv/S4P/T4P/M2//z9/+cuP/V4P9Whv9Uhf9Sg/9Pgf9NgP/8/f9di/9Xh/9lkf5aif9qlP7z9//k7P/c5v+2y/94nv51nP6lv/+LrP6Ep/6BpP5gjf7v9P+wxv/U4f/M2/+sxP+vxv73+f/P3v/J2v+5zf+ivP+fuv9xmf+Ytv6Usv6Hqf58of5vl/7m7v/g6f+zyf6QsP75+//q8P/B0v/W4//C1P6+0P6qwv6ct/76fHZiAAAAGnRSTlMAGAaVR/Py45aC9Mfy2b8t9OPZ2ce/v4L0x/e74/EAAAIZSURBVDjLZVPXYuIwEDSmQ4BLv5O0ku3Yhwu2IZTQe0hy7f8/57QSoYR5sVea1c424wgzl324LRRuH7I507hEJluYucCFEOBGhWzmy7X5+N0WwIjTbrcdBsKulM0z96onGCGE2X6n+cTkj/CqJ480igzkNXp26E9JkABSbBz8i4Bn3EkH840mKHoxs49fZQzt2Kd03FQEzSB3WsejB9Jqf1CJQBM0wCurABWBoub0gkDENwyStTHA62pwSWDtklRQ4FLfjnaiPqVW60hAYeLKNHIREOZuKTL80H6XBFCwn4BAmDOyLiOQUIlOSEjaoS+Ju57NZuul73Fml4w6yAivSLBW3MGfcfBmIegmArg3alICdJHgy1jQt8Z/6CcC4DdGXhLIoiWRACpbLYbDYW80GnXp2GH8ShP+PUvEoHsAIFq9Xm8+kXlIwkkI9pm+05Tm3yWqu9EiB0pkwjWBx2i+tND1XqeZqpPU4VhUbq/ekR8CwTRVoRxf3ifTbeIwcONNsJZ2lxFVKDMv1KNvS2zXdrnD+COvR1PQpTZKNlKD3cLCOJNnivgVxkw169BunlKFaV9/B+LQbqOsByY4IVgDB59dl/cjR9TIJV1Lh7CGqUqH/DDPhhZYOPkdLz6m0X7GrzPHsSe6zJwzxvm+5NeNi8U5ABfn7mz7zHJFrZ6+BY6rd7m8kQtcAtwwXzq4n69/vZbP1+pn6/8fsrRmHUhmpYYAAAAASUVORK5CYII="

# 截取 data:image/png;base64,后面部分的数据即可
s = source.split(",")[1]
with open("a.png", "wb") as f:
    f.write(base64.b64decode(s))
  • 23
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

My.ICBM

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值