什么是Base64算法
HTTP是超文本传输协议,所以HTTP协议中请求、相应都是以ASCII字符方式传输,如果要传输二进制需要经过BASE64或MIME等编码(因为HTTP协议pop3、smtp邮件协议都是针对文本的,而FTP支持传输二进制数据,即不需要经过编码转换成字符型数据)
HTTP传输字节流时为什么会用Base64编码
可能很多人不明白,为什么在进行HTTP传输时二进制数据时,需要将字节流进行Base64编码呢?
可能很多小伙伴都会认为,HTTP传输文本底层仍然是字节流数据,为什么我通过HTTP请求直接传输文件的字节流还需要进行编码呢?
因为HTTP是文本协议,它只能传输ASCII码表中可打印字符的编码(类似的还有SMTP邮件协议),ASCII码表的范围是0-127(只需要一个字节中的七位),而一个字节是八位,这也意味着原本8bit字节码(范围0-255)超过了可用范围,因此无法被传输(ASCII码中有一部分控制字符,它们同样无法传输)。例如:当传输图片时某一个byte的值是0x10111011,对应的十进制是187不属于ASCII码的范围,因此无法被传输。
注:ASCII码的范畴是0-127,其中0-31和127这33个字符属于控制字符。
Base64原理
把3个8bit字节(3x8=24)转换为4个6位的字节(4x6=24),之后每个六位的前面补0,形成完整8bit字节。在根据每个字节的值,用下表中的值进行替换,不足四个字节的补=:

向下图中,8bit x 3的字符串可以每6个bit分成一组,每一组bit对应一个十进制index,每个index又对应了Base64字符。

最终,8bit字符串Man编码成了Base64的TWFu。相比8bit的字符编码,Base64编码会多占用三分之一的字节长度,以此为代价实现了更好的兼容性。
如果原本8bit字符串长度不是3的倍数,例如我们需要对长度为1个字节的数据进行编码,Base64会对匹配不到8bit字节的6bit字节位用=填充:

Java中Base64编码与解码的使用
早期用法(不建议)
final BASE64Encoder encoder = new BASE64Encoder();
final BASE64Decoder decoder = new BASE64Decoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encode(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decodeBuffer(encodedText), "UTF-8"));
final BASE64Encoder encoder = new BASE64Encoder();
final BASE64Decoder decoder = new BASE64Decoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encode(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decodeBuffer(encodedText), "UTF-8"));
从以上程式可以发现,在Java用Base64一点都不难,不用几行程式码就解决了!只是这个sun.mis c套件所提供的Base64功能,编码和解码的效率并不太好,而且在以后的Java版本可能就不被支持了,完全不建议使用。
Java 8之后的作法
Java 8的java.util套件中,新增了Base64的类别,可以用来处理Base64的编码与解码,用法如下:
final Base64.Decoder decoder = Base64.getDecoder();
final Base64.Encoder encoder = Base64.getEncoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decode(encodedText), "UTF-8"));
final Base64.Decoder decoder = Base64.getDecoder();
final Base64.Encoder encoder = Base64.getEncoder();
final String text = "字串文字";
final byte[] textByte = text.getBytes("UTF-8");
//编码
final String encodedText = encoder.encodeToString(textByte);
System.out.println(encodedText);
//解码
System.out.println(new String(decoder.decode(encodedText), "UTF-8"));
文章参考:
https://www.cnblogs.com/alter888/p/9140732.html
什么是Base64算法的更多相关文章
- MD5加密、时间戳转换、base64算法加密、解密
#region MD5加密 /// <summary> /// MD5加密 /// </summary> /// <param name="str"& ...
- java Base64算法的使用
Base64是常见的网络加密算法,Base64编码可用于在HTTP环境下传递较长的标识信息.详见 Base64介绍 1 自定义的base64算法 Base64Encrypt.java public c ...
- Base64算法
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/4288372.html ...
- MD5加密算法(信息摘要算法)、Base64算法
1 什么是MD5 信息摘要算法,可以将字符进行加密,每个加密对象在进行加密后都是等长的 应用场景:将用户密码经过MD5加密后再存储到数据库中,这样即使是超级管理员也没有能力知道用户的具体密码是多少:因 ...
- c# base64算法解密
/// <summary> /// 将字符串使用base64算法加密 /// </summary> /// <param name="code_type&quo ...
- java基础---->Base64算法的使用
Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,可用于在HTTP环境下传递较长的标识信息.详细的Base64信息,可以参见维基百科:https://en.wikipedia.org ...
- 【转】Base64算法详解
原文链接:https://blog.csdn.net/robertcpp/article/details/51628647 完整的BASE64定义可见RFC 1421和RFC 2045.编码后的数据比 ...
- java Base64算法
Base64算法并不是加密算法,他的出现是为了解决ASCII码在传输过程中可能出现乱码的问题.Base64是网络上最常见的用于传输8bit字节码的可读性编码算法之一.可读性编码算法不是为了保护数据的安 ...
- Base64 算法原理,以及编码、解码【加密、解密】 介绍
Base64编码,是我们程序开发中经常使用到的编码方法.它是一种基于用64个可打印字符来表示二进制数据的表示方法.它通常用作存储.传输一些二进制数据编码方法!也是MIME(多用途互联网邮件扩展,主要用 ...
- 传奇的通迅协议与base64算法
传奇的数据根本就没加密. 只要把#(数字)!去掉,中间的那些全部减0x3c,然后,四个字节一组,每个字节取低六位组成6*4=24位,然后分成3个字节,这个是很经典的base64的算法.不过小改了一些, ...
随机推荐
- C++调用Python-0:搭建环境
1.进入到Python安装目录 2.将Python安装目录中的 include 和 libs 文件夹放在 C++项目中 3.设置 附加包含目录 和 附加库目录.附加依赖项(python310_d.li ...
- 第二十篇:cookie和session
一.Cookie是什么鬼 二.基于cookie实现用户登录 三.基于cookie实现定制显示数据条数 四.带签名的cookie 五.CBV和FBV用户认证装饰器
- Flutter笔记 - 事件分发
事件处理流程 Flutter 事件处理流程主要分两步,为了聚焦核心流程,我们以用户触摸事件为例来说明: 命中测试:当手指按下时,触发 PointerDownEvent 事件,按照深度优先遍历当前渲染( ...
- 元素类型 “item” 相关联的 “name” 属性值不能包含 ‘<’ 字符
Android构建时报错: app:lintVitalRelease[Fatal Error] :3:214: 与元素类型 "item" 相关联的 "name" ...
- Kruise Rollout:灵活可插拔的渐进式发布框架
简介: Kruise Rollout 是 OpenKruise 社区开源的渐进式交付框架.Kruise Rollout 支持配合流量和实例灰度的金丝雀发布.蓝绿发布.A/B Testing 发布,以及 ...
- 如何落地云原生DevOps?
简介: 什么是云原生DevOps?在阿里内部有怎样的实践?企业又该如何落地?阿里云云效专家团队提出了下一代精益产品开发方法体系--ALPD,提供了系统的云原生DevOps落地的方法支撑,帮助企业渐进式 ...
- EventBridge 与 FC 一站式深度集成解析
简介:本篇文章通过对 EventBridge 与 FC 一站式深度集成解析和集成场景的介绍,旨在帮助大家更好的了解面对丰富的事件时,如何使用 EventBridge 与 FC 的一站式集成方案,快速 ...
- WPF 使用 Silk 的 Direct2D 入门
在上一篇博客的基础上,使用 dotnet 基金会新开源的 Silk.NET 库,让 Silk.NET 创建的 DX 设备和 WPF 对接渲染.接下来本文将告诉大家如何使用 Silk.NET 提供的 D ...
- WinDbg 设置在加载到某个 DLL 进入断点
本文记录如何在 WinDbg 里,设置在加载到某个 DLL 时,自动进入断点.通过此方式用来定位是哪个业务模块加载了某个 DLL 模块 在 WinDbg 里面,可以附加到现有进程,也可以启动某个进程. ...
- dotnet 记 TaskCompletionSource 的 SetException 可能将异常记录到 UnobservedTaskException 的问题
本文将记录 dotnet 的一个已知问题,且是设计如此的问题.假定有一个 TaskCompletionSource 对象,此对象的 Task 没有被任何地方引用等待.在 TaskCompletionS ...