(一)Base64是什么
Base64编码,是由64个字符组成编码集:26个大写字母A-Z,26个小写字母a-z,10个数字0-9,符号“+”与符号“/”。Base64编码的基本思路是将原始数据的三个字节拆分转化为四个字节,然后根据Base64的对应表,
得到对应的编码数据。
当原始数据凑不够三个字节时,编码结果中会使用额外的符号“=”来表示这种情况。

(二)Base64原理

base64编码_字符串


由于64等于2的6次方,所以一个Base64字符实际上代表着6个二进制位(bit)。

然而,二进制数据1个字节(byte)对应的是8比特(bit),因此,3字节(3 x 8 = 24比特)的字符串/二进制数据正好可以转换成4个Base64字符(4 x 6 = 24比特)。

为什么是3个字节一组呢? 因为6和8的最小公倍数是24,24比特正好是3个字节。

具体的编码方式:
将每3个字节作为一组,3个字节一共24个二进制位
将这24个二进制位分为4组,每个组有6个二进制位
在每组的6个二进制位前面补两个00,扩展成32个二进制位,即四个字节
每个字节对应的将是一个小于64的数字,即为字符编号
再根据字符索引关系表,每个字符编号对应一个字符,就得到了Base64编码字符

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

base64编码_数据_02

解释:
1.字符转ascii码(ascii码是10进制的)
2.ascii码转二进制位(一共24比特位)
3.二进制位以每6个,分成4个编码字节组
4.每个编码字节组对应一个base64表里的编号
5.输出是base64编码

import base64

s1 = "you"
ret = base64.b64encode(s1.encode()) #需要s1转成二进制位
print(ret) # b"eW91"
print(ret.decode()) # eW91
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

小于3个字符为一组的编码方式如下

base64编码_数据_03

import base64

s1 = "yo"
ret = base64.b64encode(s1.encode()) #需要s1转成二进制位
print(ret) # b"eW8="
print(ret.decode()) # eW8=
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

最重要的是3换4, 不足3的会补齐

解码

import base64

s1 = "you"
ret = base64.b64encode(s1.encode()) #需要s1转成二进制位
print(ret) # b"eW91"
print(ret.decode()) # eW91

# 解码
s2 = base64.b64decode(ret).decode()
print(s2) # b'you'
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

(三)base64原理图

base64编码_PHP_04


最后处理完的编码字符再转字节中不再有base64以外的任何字符

例子:

# 有的时候,会对后面的=号去除了来混淆视听,所以解码的时候补齐

s1 = "eW8"

s1+=(4 - len(s1) % 4) * '='
print(s1)

# 解码
s2 = base64.b64decode(s1).decode()
print("sss",s2) # b'yo'
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

(四)base64变种
在一个base64码中“+”被替换成“-”,“/”被替换成“—”
需要我们替换回来
如果没有成功,需要去js里看一下

(五)为什么用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编码_PHP_05

对上面的数据(图片)进行解码

import base64

img_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="
img_bytes = base64.b64decode(img_base64)
print(img_bytes)
with open("a.png","wb") as f:
    f.write(img_bytes)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.

(六)js中的编码解码

编码:btoa
解码:atob
btoa("you")
>>>>>'eW91'
atob("eW91")
>>>>>'you'
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

(七)php中的编码解码
在PHP中,进行Base64编码和解码是非常简单的,主要依赖于两个内置函数:base64_encode()base64_decode()

Base64 编码
base64_encode() 函数用于将字符串编码成Base64格式。这个函数接受一个字符串作为输入,并返回该字符串的Base64编码结果。

示例代码:

<?php  
$data = "you";  
$encodedData = base64_encode($data);  
echo $encodedData; // 输出:eW91
?>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

Base64 解码
base64_decode() 函数用于将Base64编码的字符串解码回原始字符串。这个函数接受一个Base64编码的字符串作为输入,并返回原始字符串。

示例代码:

<?php  
$encodedData = "eW91";  
$decodedData = base64_decode($encodedData);  
echo $decodedData; // 输出:you
?>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

注意事项

  • Base64编码后的字符串会包含+、/、=等特殊字符,这些字符在某些环境(如URL)中可能需要被转义或替换。
  • 当解码一个非Base64编码的字符串时,base64_decode() 可能会返回一些非预期的字符(如NULL字符),因为它试图将任何输入都解码为可能的字节序列。因此,在解码之前,确保字符串是有效的Base64编码是很重要的。
  • PHP的Base64函数处理的是二进制数据,所以它们非常适合用于编码和解码图像、文件等二进制数据。
  • 对于URL中的Base64字符串,你可能需要将+替换为-,/替换为_,并删除尾部的=(如果有的话),因为这些字符在URL中有特殊含义。然后,在解码之前,你可能需要将这些修改后的字符再转换回原来的Base64字符。不过,PHP的urlsafe_b64encode() 和 urlsafe_b64decode() 函数(需要PHP 5.6.0及以上版本)可以直接处理URL安全的Base64编码和解码,无需手动替换字符。然而,请注意这两个函数并不是PHP核心函数,它们可能不在所有PHP安装中都可用,除非你使用了支持它们的扩展或库。对于标准的Base64处理,你应该使用base64_encode()和base64_decode()。对于URL安全的Base64编码,你可能需要自己实现替换逻辑或使用现成的库。