Base64编码是最常见的编码方式(使用64个字符表示任意8bit字节序列),是一种基于64个可打印字符来表示任意二进制数据的方法,是从二进制转换到可见字符的过程。

使用场景

  • 数据加密后通过Base64转换为可见字符串存储
  • URL(需要Url安全的Base64)、Cookie、网页中传输少量二进制数据
  • 将二进制数据(比如图片)保存在文本文件中
  • 不能传输二进制文件的网络环境可以转换Base64在进行网络传输

Base64原理

【Base64编码表】

对二进制数据进行处理,把每3个字节(每个字节为 8bit, 3个字节为24bit)重新划为4组(每组为6bit后,高位补两个 0 为8bit 后作为一个新字节。划分后对应的二进制数值范围是 00000000 - 00111111(十进制范围 0 - 63),正好和码表字符个数对应。), 然后将划分后的字节转换为4个数字作为索引查编码表,获得相应的4个字符,从而得到编码后的字符串。

以字符串 “ABC” 为例,将其Base64编码:

“ABC” 的二进制为 -> 01000001 01000010 01000011

如果要编码的数据二进制位数不是3的倍数,那么最后会在编码的末尾加上1个或2个 = 号进行补足,表示补了多少字节,解码的时候会被去掉。

以字符串 “A” 为例,将其Base64编码:

“A” 的二进制为 -> 01000001

Base32 和 Base16

除Base64外 ,还有不常用的Base32 和 Base16编码,Base32 是将 5个字节拆分为8组,Base16是将 1个字节拆分为2组, 和Base64编码原理是一样的。

Base32:使用26个大写字母A-Z和数字2-7的32个字符做为字符集。Base32字符集中省略了1,0等数字,记忆或手写它们,容易与字母 I, O 混淆。

【Base32编码表】

Base16:使用数字0-9和字母A-F或小写a-f的16个字符做为字符集。

【Base16编码表】

Base64编码后会使数据增大

因为Base64对二进制数据进行处理时,会将每3个字节(每个字节8bit,共为24bit),划分为4个字节,会使数据增大。

JDK提供的Base64编码方法

在Java7之前可以使用sun.misc.BASE64Encoder和sun.misc.BASE64Decoder,用来Base64编码解码,com.sun开头的包不是公开的,属于sun的内部方法,不建议使用。所以可以使用Apache提供的工具包(commons-codec-1.11.jar)来进行Base64编码解码。

从JDK 7开始Oracle发表了声明,不希望Java程序调用JDK系统包中以sun开头的类(请见:https://www.oracle.com/technetwork/java/faq-sun-packages-142232.html)。

从JKD 8开始,Oracle已经把Base64进行优化并放到JDK的java.util包里了,所以推荐直接使用java.util.Base64进行Base64编码和解码。

例:

// Base64 编码
String encoder = Base64.getEncoder().encodeToString("但愿人长久 千里共婵娟".getBytes());
System.err.println(encoder);
// Base64 解码
String decoder = new String(Base64.getDecoder().decode(encoder));
System.err.println(decoder); // 结果
// 5L2G5oS/5Lq66ZW/5LmFIOWNg+mHjOWFseWpteWonw==
// 但愿人长久 千里共婵娟

上面标准的Base64编码后可能出现字符 + 和 /,如果用在URL中,就不能直接作为参数,所以又有一种URL安全的Base64编码,就是把字符 + 和 / 分别变成 - 和 _ ,JDK 也提供了对应的方法。

例:

// URL安全的Base64 编码
String safeEncoder = Base64.getUrlEncoder().encodeToString("但愿人长久 千里共婵娟".getBytes());
System.err.println(safeEncoder);
// URL安全的Base64 解码
String safeDecoder = new String(Base64.getUrlDecoder().decode(safeEncoder));
System.err.println(safeDecoder); // 结果
// 5L2G5oS_5Lq66ZW_5LmFIOWNg-mHjOWFseWpteWonw==
// 但愿人长久 千里共婵娟

小结

Base64 是一种把任意二进制数据转换为字符串序列过程

Base64 不能用于真正意义上的数据加密


参考:

https://tools.ietf.org/html/rfc4648

https://en.wikipedia.org

了解一下 - Base64的更多相关文章

  1. URL安全的Base64编码

    Base64编码可用于在HTTP环境下传递较长的标识信息.在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式.此时,采用Base64编码不仅比较简短,同时也具有不可 ...

  2. Base64编码

    Base64编码 写在前面 今天在做一个Android app时遇到了一个问题:Android端采用ASE对称加密的数据在JavaWeb(jre1.8.0_7)后台解密时,居然解密失败了!经过测试后发 ...

  3. Android数据加密之Base64编码算法

    前言: 前面学习总结了平时开发中遇见的各种数据加密方式,最终都会对加密后的二进制数据进行Base64编码,起到一种二次加密的效果,其实呢Base64从严格意义上来说的话不是一种加密算法,而是一种编码算 ...

  4. java单向加密算法小结(1)--Base64算法

    从这一篇起整理一下常见的加密算法以及在java中使用的demo,首先从最简单的开始. 简单了解 Base64严格来说并不是一种加密算法,而是一种编码/解码的实现方式. 我们都知道,数据在计算机网络之间 ...

  5. URI编码解码和base64

    概述 对于uri的编解码,在js中有3对函数,分别是escape/unescape,encodeURI/decodeURI,encodeURIComponent/decodeURIComponent. ...

  6. 通过HTML5的Drag and Drop生成拓扑图片Base64信息

    HTML5 原生的 Drag and Drop是很不错的功能,网上使用例子较多如 http://html5demos.com/drag ,但这些例子大部分没实际用途,本文将搞个有点使用价值的例子,通过 ...

  7. Base-64 字符数组或字符串的长度无效等问题解决方案

    项目特殊需要,调用ActiveX三维控件进行控件某一特殊部位的截图操作,这个截图保存由ActiveX控件控制保存到本地是没问题的,现在需要将这个截图上传到服务器,多人共享,就牵扯到需要读取本地文件…… ...

  8. android Base64 加密

    一 Base64加密 import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.OutputStre ...

  9. When I see you again(加密原理介绍,代码实现DES、AES、RSA、Base64、MD5)

    关于网络安全的数据加密部分,本来打算总结一篇博客搞定,没想到东西太多,这已是第三篇了,而且这篇写了多次,熬了多次夜,真是again and again.起个名字:数据加密三部曲,前两部链接如下: 整体 ...

  10. 网络安全——Base64编码、MD5、SHA1-SHA512、HMAC(SHA1-SHA512)哈希

    据说今天520是个好日子,为什么我想起的是502.500.404这些?还好服务器没事! 一.Base64编码 Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之 ...

随机推荐

  1. Lucene 源码分析之倒排索引(三)

    上文找到了 collect(-) 方法,其形参就是匹配的文档 Id,根据代码上下文,其中 doc 是由 iterator.nextDoc() 获得的,那 DefaultBulkScorer.itera ...

  2. 从零开始学 Web 之 CSS(三)链接伪类、背景、行高、盒子模型、浮动

    大家好,这里是「 Daotin的梦呓 」从零开始学 Web 系列教程.此文首发于「 Daotin的梦呓 」公众号,欢迎大家订阅关注.在这里我会从 Web 前端零基础开始,一步步学习 Web 相关的知识 ...

  3. 【SQL】面面俱到 | 在SQL中使用CUBE和ROLLUP实现数据多维汇总

    偶然在网上看到一篇文章,讲到数据汇总,提到了CUBE,感觉有些晦涩,想试着自己表述一下.同时,个人也认为CUBE还是很有用的,对SQL或数据分析感兴趣的小伙伴不妨了解一下,或许有用呢! 先设定个需求, ...

  4. 全面理解 javascript 的 argements caller callee call apply 之caller

    /** * 演示arguments的用法,如何获取实参数和形数数 */ function argTest(a,b,c,d){ var numargs = arguments.length; // 获取 ...

  5. Java ArrayList正确循环添加删除元素方法及分析

    在阿里巴巴Java开发手册中,有这样一条规定: 但是手册中并没有给出具体原因,本文就来深入分析一下该规定背后的思考. 一.foreach循环 foreach循环(Foreach loop)是计算机编程 ...

  6. C# - 为引用类型重定义相等性

    通常情况下引用类型的相等性是不应该被重定义/重写的. 例如两个引用类型的变量 x 和 y,如果这样写:if(x == y) {...},那么大家都明白,这个比较的是引用的相等性. 但是有少数情况下,也 ...

  7. HTTP/2 简介

    支撑现有 Web 服务的 HTTP 协议距离其发布时的 1997 年已经有些年月了,随后的 HTTP/1.1 版本发布自 1999 年.随着技术的进步和需求的进化,对于数据快速高效地传输,HTTP/1 ...

  8. Asp.Net Core 轻松学-基于微服务的后台任务调度管理器

    前言     在 Asp.Net Core 中,我们常常使用 System.Threading.Timer 这个定时器去做一些需要长期在后台运行的任务,但是这个定时器在某些场合却不太灵光,而且常常无法 ...

  9. java基础(八)-----深入解析java四种访问权限

    Java中的访问权限理解起来不难,但完全掌握却不容易,特别是4种访问权限并不是任何时候都可以使用.下面整理一下,在什么情况下,有哪些访问权限可以允许选择. 一.访问权限简介 访问权限控制: 指的是本类 ...

  10. Morris遍历-如何用空间复杂度O(1)来遍历二叉树

    参照和学习: https://www.cnblogs.com/AnnieKim/archive/2013/06/15/morristraversal.html 解决的问题:如何使用空间复杂度O(1), ...