hi,大家好,我是开发者FTD。相信很多同学在工作中,经常会用到Base64编码,那大家知道为什么会有Base64编码吗?我们为什么要使用它呢,它又是怎么实现的呢?下面就让我们来一起深入探究一下Base64编码吧。

Base 家族

在开始之前,我们先给大家介绍一下Base家族。虽然我们在工作中使用最多的是Base64,但是Base家族可不止是只有Base64,除了Base64之外,Base家族还有Base32和Base16。

我们都知道ASCII 编码,ASCII 编码是用256(2的8次方)个字符,对二进制数据进行编码的方式,同样的

  • Base64 编码是用64(2的6次方)个字符,对二进制数据进行编码的方式

  • Base32 编码是用32(2的5次方)个字符,对二进制数据进行编码的方式

  • Base16 编码是用16(2的4次方)个字符,对二进制数据进行编码的方式

那Base家族有这么多编码形式,为什么偏偏使用Base64呢?

  • Base64 编码是用64(2的6次方)个特定的ASCII字符来表示256(2的8次方)个ASCII字符,也就是说三个ASCII字符经过Base64编码后变为四个的ASCII字符显示(公约数为24),编码后数据长度比原来增加1/3,不足3n用“=”补足。

  • Base32 编码就是用32(2的5次方)个特定的ASCII字符来表示256(2的8次方)个ASCII码,也就是说五个ASCII字符经过Base32编码后会变为八个ASCII字符显示(公约数为40),编码后数据长度比原来增加3/5,不足8n用“=”补足。

  • Base16 编码就是用16(2的4次方)个特定的ASCII字符表示256(2的8次方)个ASCII字符,也就是说一个ASCII字符经过Base16编码后会变为两个ASCII字符显示,编码后数据长度比原来增加一倍,不足2n用“=”补足。

从上面可以看出Base64编码后,长度增加是最少的,这也是我们选用Base64的一个重要原因。

Base64 简介

Base64顾名思义,就是基于64个可打印字符来表示二进制数据的一种方法,注意它并不是一种加密算法。对于64个打印字符,我们只需要6个二进制位就可以完全表示了。那么我们如何利用8个二进制位来表示只需要6个二进制位就可以完全表示的可打印字符呢?由于2的6次方等于64,所以我们可以将每6个位元为一个单元,对应某个可打印字符。三个字节有24个位元,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。

Base64是从二进制数据到字符的过程。所以计算机中所有的内容,包括文本、图片、音频、视频等等都可以使用Base64编码来表示。

Base64 编码原理

Base64编码就是使用64个字符作为一个基本字符集:

小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"(再加上作为垫字的"=",实际上是65个字符)

然后,所有其他符号都根据一定规则转换成这个字符集中的字符。

具体来说,Base64编码的转换方式可以分为以下四步:

  • 第一步,将每三个字节作为一组,一共是24个二进制位
  • 第二步,将这24个二进制位分为四组,每个组有6个二进制位
  • 第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节
  • 第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值

Base64 编码的字符索引表如下所示:

数值 字符 数值 字符 数值 字符 数值 字符
0 A 16 Q 32 g 48 w
1 B 17 R 33 h 49 x
2 C 18 S 34 i 50 y
3 D 19 T 35 j 51 z
4 E 20 U 36 k 52 0
5 F 21 V 37 l 53 1
6 G 22 W 38 m 54 2
7 H 23 X 39 n 55 3
8 I 24 Y 40 o 56 4
9 J 25 Z 41 p 57 5
10 K 26 a 42 q 58 6
11 L 27 b 43 r 59 7
12 M 28 c 44 s 60 8
13 N 29 d 45 t 61 9
14 O 30 e 46 u 62 +
15 P 31 f 47 v 63 /

有了这个字符索引表,我们就可以把任意的二进制转换成Base64的编码了,下面我们通过几个例子,给大家展示一下转换的过程。

1,假设现在有字符串 FTD 需要转换成base64的编码格式

  • 第一步:“F”、“T”、“D” 字符对应的ASCII码值分别为70,84,68,对应的二进制值是01000110、01010100、01000100。如图第二三行所示,由此组成一个24位的二进制字符串。
  • 第二步:将24位二进制按照每6位二进制位一组分成四组。
  • 第三步:在上面每一组前面补两个0,扩展成32个二进制位,此时变为四个字节:00010001、00100101、00010001、00000100。分别对应的值(Base64编码索引)为:17、37、17、4。
  • 第四步:用上面的值在Base64 字符索引表中进行查找,分别对应:R、I、R、E。

因此字符串 “FTD” 经过Base64 编码之后就变为:RIRE 。

2,上面的例子中的字符正好是三个字节,如果字节数不足三个时该如何处理呢?下面我们以 FFT 分别举例说明如下:

如上表所示,由于字符F的二进制为01000110,按照每6位进行分组,此时只能分成一组,第二组缺少4位,如果位数不足时,用0补齐;第三组和第四组完全没有数据,则用**=补上。因此,字符F经过Base64编码后得到的数值为Rg==**。

3,下面我们再看一下如果只有两个字符的情况:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BIpbsJ8y-1614862870049)(https://i.loli.net/2021/02/13/SF5zvPMbNTRtsh8.png)]

如上表所示,这个也属于位数不足,需要补位的情况。第一组和第二组按照正常的分组计算,第三组由于不足位数,最后两位补0,第四组完全没有数据,用**=补上。因此,字符FT经过Base64编码后得到的数值为RlQ=**。

关于中文的Base64编码

大家都知道中文编码有很多种,例如GB2312、GBK、GB18030,不同的汉字使用不同的编码格式进行编码后,它的二进制是不同的,所以在进行Base64编码后,他们的Base64编码的值也是不同的。这就要求我们在解码的时候需要注意原文的字符集格式,一定要保持一致才能正确解码。

例如:

中文 “【我是开发者FTD】公众号” UTF-8 格式的Base64 编码后的值是:44CQ5oiR5piv5byA5Y+R6ICFRlRE44CR5YWs5LyX5Y+3

中文 “【我是开发者FTD】公众号” GB2312 格式的Base64 编码后的值是:ob7O0srHv6q3otXfRlREob+5q9bausU=

Base64 是加密算法吗?

Base64 主要不是用来加密的,它主要的用途是把一些二进制数转成普通字符用于网络传输,这是因为一些二进制字符在传输协议中属于控制字符,不能直接在网络上传输。另外,还有一些系统中只能使用ASCII字符。Base64 编码就是用来将非ASCII字符的数据转换成ASCII字符的一种方法。Base64 并不是安全领域下的加密解密算法,虽然有时候也会经常看到所谓的Base64加密解密算法。其实Base64只能算是一个编码算法,对数据内容进行编码来适合网络传输。虽然Base64编码过后原文也变成无法直接理解的字符格式,但是这种编码方式比较初级,很简单,很容易就可以被还原成原文,所以如果有比较重要的信息需要加密,一定要使用我们之前文章中介绍的那些加密算法进行数据的安全保护。

Base64 编码实现

Java语言中有多个库实现了Base64编码,不管哪一个库,最终的结果都是一样的。

JDK 提供的 Base64 编码实现:

public static String encode(String data) {return Base64.getEncoder().encodeToString(data.getBytes());
}public static String decode(String base64Data) {return new String(Base64.getDecoder().decode(base64Data));
}

Bouncy Castle 提供的 Base64 编码实现:

public static String encode(String data) {return new String(Base64.encode(data.getBytes()));
}public static String decode(String base64Data) {return new String(Base64.decode(base64Data));
}

Commons Codec 提供的 Base64 编码实现:

public static String encode(String data) {return Base64.encodeBase64String(data.getBytes());
}public static String decode(String base64Data) {return new String(Base64.decodeBase64(base64Data));
}

下面让我们用Java语言的实现来验证一下,我们第二章节的推理是否正确吧,代码如下:

public static void main(String[] args) {String ftd = "FTD";String ft = "FT";String f = "F";System.out.println("FTD base64 编码:" + encode(ftd));System.out.println("FT base64 编码:" + encode(ft));System.out.println("F base64 编码:" + encode(f));
}

输出结果为:

FTD base64 编码:RlRE
FT base64 编码:RlQ=
F base64 编码:Rg==

可以看到,和我们分析所得的结果是完全一样的。

查看完整代码请访问:

https://github.com/ForTheDevelopers/JavaSecurity

总结

Base64是我们在工作中经常用到,但是很少有人会深入研究一下它的实现原理,如果理解不当,甚至可能还会有人用它当做加解密用到业务系统关键位置,可能会引发比较严重的后果,相信大家看完上述的内容后,应该对Base64编码已经有了深刻的理解了吧。

技术人,技术魂,每天肝一篇技术文,ヾ(◍°∇°◍)ノ゙哈哈~

关于作者
  • GitHub:https://github.com/ForTheDevelopers
  • 掘金:https://juejin.cn/user/1204720472953022
  • CSDN:https://blog.csdn.net/ForTheDevelopers
  • 知乎:https://www.zhihu.com/people/forthedevelopers
  • segmentfault:https://segmentfault.com/u/for_the_developers
联系作者
  • 微信号:ForTheDeveloper

  • 公众号:ForTheDevelopers

一文带你读懂base64编码相关推荐

  1. 一文带你读懂HTTP协议的前世今生

    点击上方蓝字关注我们 HTTP,Hypertext Transfer Protocol,超文本协议,是在万维网上传输文件(如文本.图形图像.声音.视频和其他多媒体文件)的规则集.如果web用户打开他们 ...

  2. DNN、RNN、CNN.…..一文带你读懂这些绕晕人的名词

    DNN.RNN.CNN.-..一文带你读懂这些绕晕人的名词 https://mp.weixin.qq.com/s/-A9UVk0O0oDMavywRGIKyQ 「撞脸」一直都是娱乐圈一大笑梗. 要是买 ...

  3. 一文带您读懂FCC、CE、CCC认证的区别

    一文带您读懂FCC.CE.CCC认证的区别 参考资料:https://3g.k.sohu.com/t/n411629823 FCC认证,CE认证,CCC认证是产品认证中比较常见的几个认证,前两者经常有 ...

  4. 机器学习中为什么需要梯度下降_机器学习101:一文带你读懂梯度下降

    原标题 | Machine Learning 101: An Intuitive Introduction to Gradient Descent 作者 | Thalles Silva 译者 | 汪鹏 ...

  5. 用程序员计算机算进制,一文带你读懂计算机进制

    hi,大家好,我是开发者FTD.在我们的学习和工作中少不了与进制打交道,从出生开始上学,最早接触的就是十进制,当大家学习和使用计算机时候,我们又接触到了二进制.八进制以及十六进制.那么大家对进制的认识 ...

  6. 一文带你读懂“经典TRIZ”

    本文承接上文<一文带第读懂TRIZ>,下面开始看第二个问题:什么是"经典TRIZ"? 很多书里都有对TRIZ的产生与发展的描述. 我个人在看了很多的书和文献以后,认为: ...

  7. 简单一文带你读懂Java变量的作用和三要素

    Java变量的作用 不只是java,在其他的编程语言中变量的作用只有一个:存储值(数据) 在java中,变量本质上是一块内存区域,数据存储在java虚拟机(JVM)内存中 变量的三要素 变量的三要素分 ...

  8. 一文带你读懂感知机的前世今生(上)

    一文带你读懂感知机的前世今生 前言 男女不分 什么是神经元 M-P神经元 全或无定律 McCulloch和Pitts 一种高度简化的模型 MP神经元和真值表 MP神经元的几何理解 后记 参考 前言 男 ...

  9. 《一文带你读懂:云原生时代业务监控》

    点击上方蓝字关注我们! 对业务来说,完备的应用健康性和数据指标的监控非常重要,通过采集准确的监控指标.配置合理的告警机制,我们能够提前或者尽早发现问题,并做出响应.解决问题,进而保证产品的稳定性,提升 ...

最新文章

  1. Windows下JSON可视化工具
  2. 【正则化】csdn markdown python 批量给文本行行头添加“•”符号,“- ”(实心圆)
  3. 音视频技术开发周刊 | 169
  4. 字符串匹配的Boyer-Moore算法
  5. UI5控件类似Java反射机制的一个小技巧
  6. 十大笔记本电脑排行_十大笔记本电脑品牌排行榜 世界上最受欢迎的电脑品牌...
  7. 一群阿里人如何用 10 年自研洛神云网络平台?技术架构演进全揭秘!
  8. java对象组合_java并发编程(三): 对象的组合
  9. 【2017年第3期】Talent Network:一个基于设计思维的企业社交网络服务
  10. Ubuntu系统安装向日葵
  11. 使用动态代理爬取某房产平台信息并写入Excel(python)
  12. 全球唯一顶级车展来袭,云徙科技成为造车新势力?
  13. 玩机搞机----安卓全机型修改开机第一屏步骤教程
  14. UI设计师行业是做什么的?
  15. Windows消息前缀
  16. 新版标准日本语中级_第三十二课
  17. 想知道未来孩子长相?Python人脸融合告诉你
  18. 一些个人笔记,持续更新ing
  19. c语言源码什么意思,请问C语言源代码什么意思?
  20. Ubuntu 18.04 更换阿里源

热门文章

  1. 转 Java jar (SpringBoot Jar)转为win可执行的exe程序
  2. flutter 获取设备屏幕大小
  3. SQL Server-基础-经典SQL语句
  4. 表变量和临时表的使用
  5. Silverlight 入门
  6. ZOJ 3300 Mahjong DFS暴力解决。。
  7. SpringBoot集成MyBatis的分页插件PageHelper
  8. Leetcode--172. 阶乘后的零
  9. Leetcode--113. 路径总和Ⅱ
  10. java 网页正文抽取算法_网页正文抽取算法 ContentExtractor