出自:   http://www.cnblogs.com/winner-0715/p/5920269.html

    http://www.cnblogs.com/koliop090/p/5203553.html

为什么要使用Base64?

在设计这个编码的时候,我想设计人员最主要考虑了3个问题: 
1.是否加密? 
2.加密算法复杂程度和效率 
3.如何处理传输?

加密是肯定的,但是加密的目的不是让用户发送非常安全的Email。这种加密方式主要就是“防君子不防小人”。即达到一眼望去完全看不出内容即可。 
基 于这个目的加密算法的复杂程度和效率也就不能太大和太低。和上一个理由类似,MIME协议等用于发送Email的协议解决的是如何收发Email,而并不 是如何安全的收发Email。因此算法的复杂程度要小,效率要高,否则因为发送Email而大量占用资源,路就有点走歪了。

但 是,如果是基于以上两点,那么我们使用最简单的恺撒法即可,为什么Base64看起来要比恺撒法复杂呢?这是因为在Email的传送过程中,由于历史原 因,Email只被允许传送ASCII字符,即一个8位字节的低7位。因此,如果您发送了一封带有非ASCII字符(即字节的最高位是1)的Email通 过有“历史问题”的网关时就可能会出现问题。网关可能会把最高位置为0!很明显,问题就这样产生了!因此,为了能够正常的传送Email,这个问题就必须 考虑!所以,单单靠改变字母的位置的恺撒之类的方案也就不行了。关于这一点可以参考RFC2046。 
基于以上的一些主要原因产生了Base64编码。

算法详解

Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 
具体转化形式间下图: 
字符串“张3” 
11010101 11000101 00110011

00110101 00011100 00010100 00110011 
表1

可以这么考虑:把8位的字节连成一串110101011100010100110011 
然后每次顺序选6个出来之后再把这6二进制数前面再添加两个0,就成了一个新的字节。之后再选出6个来,再添加0,依此类推,直到24个二进制数全部被选完。 
让我们来看看实际结果:

字符串“张3” 
11010101 HEX:D5 11000101 HEX:C5 00110011 HEX:33

00110101 00011100 00010100 00110011

十进制53 十进制34 十进制20 十进制51 
字符’5’ 字符’^\’ 字符’^T’ 字符’3’ (ASCII表对应的值)

表2

这样“张3 ”这个字符串就被Base64表示为”5^\^T3”了么?。错! 
Base64编码方式并不是单纯利用转化完的内容进行编码。像’^\’字符是控制字符,并不能通过计算机显示出来,在某些场合就不能使用了。Base64有其自身的编码表:

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

这 也是Base64名称的由来,而Base64编码的结果不是根据算法把编码变为高两位是0而低6为代表数据,而是变为了上表的形式,如”A”就有7位, 而”a”就只有6位。表中,编码的编号对应的是得出的新字节的十进制值。因此,从表2可以得到对应的Base64编码:

字符串“张3” 
11010101 HEX:D5 11000101 HEX:C5 00110011 HEX:33

00110101 00011100 00010100 00110011

十进制53 十进制34 十进制20 十进制51 
字符’5’ 字符’^\’ 字符’^T’ 字符’3’ (ASCII表对应的值)
字符’1’ 字符’i’ 字符’U’ 字符’z’ (Base64编码表对应的值)
表4

这样,字符串“张3”经过编码后就成了字符串“1iUz”了。 
Base64将3个字节转变为4个字节,因此,编码后的代码量(以字节为单位,下同)约比编码前的代码量多了1/3。之所以说是“约”,是因为如果代码量正好是3的整数倍,那么自然是多了1/3。但如果不是呢? 
细心的人可能已经注意到了,在The Base64 Alphabet中的最后一个有一个(pad) =字符。这个字符的目的就是用来处理这个问题的。 
当代码量不是3的整数倍时,代码量/3的余数自然就是2或者1。转换的时候,结果不够6位的用0来补上相应的位置,之后再在6位的前面补两个0。转换完空出的结果就用就用“=”来补位。譬如结果若最后余下的为2个字节的“张”:

字符串“张” 
11010101 HEX:D5 11000101 HEX:C5

00110101 00011100 00010100 
十进制53 十进制34 十进制20 pad 
字符’1’ 字符’i’ 字符’U’ 字符’=’ (Base64编码表对应的值)
表6

这样,最后的2个字节被整理成了“1iU=”。 
同理,若原代码只剩下一个字节,那么将会添加两个“=”。只有这两种情况,所以,Base64的编码最多会在编码结尾有两个“=” 
至于将Base64的解码,只是一个简单的编码的逆过程,读者可以自己探讨。

使用Apache commons codec 类Base64

maven依赖

<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.6</version>
</dependency>

Java代码实现

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException; /**
* 将String进行base64编码解码,使用utf-8
*/
public class Base64Util { private static final Logger logger = LoggerFactory.getLogger(Base64Util.class); /**
* 对给定的字符串进行base64解码操作
*/
public static String decodeData(String inputData) {
try {
if (null == inputData) {
return null;
}
return new String(Base64.decodeBase64(inputData.getBytes("utf-8")), "utf-8");
} catch (UnsupportedEncodingException e) {
logger.error(inputData, e);
} return null;
} /**
* 对给定的字符串进行base64加密操作
*/
public static String encodeData(String inputData) {
try {
if (null == inputData) {
return null;
}
return new String(Base64.encodeBase64(inputData.getBytes("utf-8")), "utf-8");
} catch (UnsupportedEncodingException e) {
logger.error(inputData, e);
} return null;
} }

Java的Base64加密原理的更多相关文章

  1. base64加密原理

    以加密字符串"HkMayfly"为例子 1.转换字符 将待加密字符串的每个字符转换为对应ASCII码的二进制形式并拓展为8位. 2.划分数据 每3个字符为一组,共24位,每6位划分 ...

  2. Java实现Base64加密

    阅读本文约“2.5分钟” Java加解密系列,介绍Java加密解密的基础知识,并使用Base64算法实现加解密. 对于加密在企业中是非常常见的,就如邮件的传输,每个企业都会有自己设置安全方式,设置加密 ...

  3. base64 加密原理 解密原理

    假设需要加密的字符串是Jasmine 具体转换步骤: 第一步 将待转换的字符串转为一个个字符第二步 计算每一个字符对应的ASCII码十进制第三步 计算出十进制对应的二进制,若不足8位,在前面添加0进行 ...

  4. Java android DES+Base64加密解密

    服务器与客户端加密解密传输, 中间遇到各种坑,客户端无论用AES还是DES解密时都会出现错误,后来才看到好多人说要用AES/DES加完密后还要BASE64加密,照做时发现android和java的Ba ...

  5. base64 数据编码原理

    例子 macOS 终端输入:echo d3d3LmNuYmxvZ3MuY29tL3poZW5nYmlu | base64 -D Linux 终端输入:echo d3d3LmNuYmxvZ3MuY29t ...

  6. Java Base64加密、解密原理Java代码

    Java Base64加密.解密原理Java代码 转自:http://blog.csdn.net/songylwq/article/details/7578905 Base64是什么: Base64是 ...

  7. password学3——Java BASE64加密解密

    Base64是网络上最常见的用于传输8Bit字节代码的编码方式之中的一个,大家能够查看RFC2045-RFC2049.上面有MIME的具体规范.Base64编码可用于在HTTP环境下传递较长的标识信息 ...

  8. C#、Java和JS实现SHA256+BASE64加密总结

    C#.Java和JS实现SHA256+BASE64加密总结 --莫非(www.muphy.me) 原理 首先,通过编码格式(UTF-8.ASCII等,如果含有汉字等字符,编码格式不同加密结果也不同)获 ...

  9. (iOS)Base64加密和DES加密、以及JAVA和iOS中DES加密统一性问题

    我们在项目中为了安全方面的考虑,通常情况下会选择一种加密方式对需要安全性的文本进行加密,而Base64加密和DES64加密是常用的加密算法.我记得我在前一个项目中使用的就是这两种加密算法的结合:Bas ...

随机推荐

  1. java中Arrays和Collections等工具类

    java.util.Arrays类能方便地操作数组,它提供的所有方法都是静态的.具有以下功能: ² 给数组赋值:通过fill方法. ² 对数组排序:通过sort方法,按升序. ² 比较数组:通过equ ...

  2. macOS 下 Visual Studio Code(VSCODE)安装配置及应用

    Visual Studio Code 重新定义了 Code 编辑. 在任何操作系统上编辑和调试应用程序内置 Git 支持1000 种以上的扩展免费和开源 为什么使用VSCODE? 我们来看看以下功能: ...

  3. bzoj 3173 最长上升子序列

    Written with StackEdit. Description 给定一个序列,初始为空.现在我们将\(1\)到\(N\)的数字插入到序列中,每次将一个数字插入到一个特定的位置.每插入一个数字, ...

  4. 分布式使用Redis

    为什么我们做分布式使用Redis? https://www.cnblogs.com/yaodengyan/p/9717080.html 绝大部分写业务的程序员,在实际开发中使用 Redis 的时候,只 ...

  5. junit学习之junit的基本介绍

    Junit目前在一些大的公司或者相对规范的软件中使用的比较多,相当多的小公司并没有把单元测试看的太重要.在大点的公司开发人员每天上班后,第一件事情就是从svn上把自己负责的代码checkout下来,然 ...

  6. 关于fft后图像的纵轴问题

    fft后如果纵轴是abs后的值,且为双边图像,那么纵轴表示的就是此频率下信号的幅值*N/2的值,也就是说,如果有一正弦信号,幅度为1,假如fft了50个点,那么此信号频率的幅度就是1*50/2=25. ...

  7. 因实现本地浏览器访问nginx修改配置文件后,安装vsftpd失败

    解决方法如下(修改dns配置) vi /etc/resolv.conf 在此文件最后加入:nameserver 8.8.8.8 如果没有vi编辑器可用: echo "nameserver 8 ...

  8. vue 相邻自定义组件渲染错误正确的打开方式

    话不多说看问题: 当封装自定义组件时例如(自定义下拉列表)两个相同的组件在多次v-if变化时偶尔会发生渲染错误,明明赋值正确但是组建中的ajax方法可能返回的数据乱掉,或者其他神逻辑错误. 经过查询发 ...

  9. Markdown 中的目录自动生成功能 TOC

    目录 Markdown 中的目录自动生成功能 TOC 1. 标题一 1.1 标题二 1.标题二 2. 标题一 2.1 标题二 2.2 标题二 Markdown 中的目录自动生成功能 TOC 1. 标题 ...

  10. Linux 绑定双网卡

    1.立即关闭iptables并禁用开机自启动[root@mysql01 ~]# /etc/init.d/iptables stop[root@mysql01 ~]# chkconfig iptable ...