Java中的Base64详解
详解Java中的Base64原理跟用法
简介
Base64编码,是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方法。它通常用作存储、传输一些二进制数据编码方法, 也是MIME(多用途互联网邮件扩展,主要用作电子邮件标准)中一种可打印字符表示二进制数据的常见编码方法。它其实只是定义用可打印字符传输内容一种方法,并不会产生新的字符集。严格来说Base64并不是一种加密/解密算法,而是一种编码方式。Base64不生成密钥,通过Base64编码后的密文就可以直接“翻译”为明文,但是可以通过向明文中添加混淆字符来达到加密的效果。
Base64实现转换原理
它是用64个可打印字符表示二进制所有数据方法。由于2的6次方等于64,所以可以用每6个位元为一个单元,对应某个可打印字符。我们知道三个字节有24个位元,就可以刚好对应于4个Base64单元,即3个字节需要用4个Base64的可打印字符来表示。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9 ,这样共有62个字符,此外两个可打印符号在不同的系统中一般有所不同。但是,我们经常所说的Base64另外2个字符是:“+/”。这64个字符,所对应表如下:
转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的bit用0补足。然后,每次取出6个bit,按照其值选择
**ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/**
中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。
如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。
编码后的数据比原始数据略长,为原来的4/3。无论什么样的字符都会全部被编码,因此不像Quoted-printable编码,还保留部分可打印字符。所以,它的可读性不如Quoted-printable编码!
M的Ascii码是77,前六位对应值为19,对应base64字符是T,如此类推。其它字符编码就可以自动转换得到!我们看看另外不是刚好是3个字节的情况!
代码示例
import java.io.UnsupportedEncodingException;/*** @Description 演示Base64的加密、解密* @author ShengLiu* @date 2018/6/20*/
public class Base64Demo {public static void main(String[] args) {//加密System.out.println(Base64Demo.getBase64Encode("Hello,World!"));//解密System.out.println(Base64Demo.getBase64Decode("SGVsbG9Xb3JsZA=="));}public static String getBase64Encode(String str) {if (str == null || "".equals(str)) {return "";}try {byte[] bt = str.getBytes("UTF-8");str = String.valueOf(Base64.encode(bt));} catch (UnsupportedEncodingException e) {e.printStackTrace();}return str;}public static String getBase64Decode(String str) {if (str == null || "".equals(str)) {return "";}char[] ch = str.toCharArray();byte[] bt = Base64.decode(String.valueOf(ch));try {str = new String(bt,"UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}return str;}
}
输出结果
SGVsbG/vvIxXb3JsZCE=
HelloWorld
代码示例
package com.test.demo;import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;import java.io.UnsupportedEncodingException;/*** @Description Base64的加密、解密测试* @author ShengLiu* @date 2018/6/20*/
public class Base64 {public static void main(String[] args) {System.out.println(Base64.getBase64Encode("你们好!!!"));System.out.println(Base64.getBase64Decode("5L2g5Lus5aW977yB77yB77yB"));}// 加密public static String getBase64Encode(String str) {byte[] b = null;String s = null;try {b = str.getBytes("utf-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();}if (b != null) {s = new BASE64Encoder().encode(b);}return s;}// 解密public static String getBase64Decode(String s) {byte[] b = null;String result = null;if (s != null) {BASE64Decoder decoder = new BASE64Decoder();try {b = decoder.decodeBuffer(s);result = new String(b, "utf-8");} catch (Exception e) {e.printStackTrace();}}return result;}
}
输出结果
5L2g5Lus5aW977yB77yB77yB
你们好!!!
sun.misc.BASE64Encoder详解
(一)、BASE64编码规则及JAVA中的使用
1、编码规则:
Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。
例如字符串“张3” :
11010101 11000101 00110011
用十进制表示即为:53 34 20 51
这个并不是最终的结果,还需要根据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
- 以上一共是64个编码,这也是Base64名称的由来。
- 编码的编号(1-64)对应的是得出的新字节的十进制值。因此,上例中字符串“张3”经过编码后就成了字符串“1iUz”了。
- 若要对只有两个字节的字符串进行编码,如“张”,则在其编码结果的后面加“=”,即“1iU=”。
- 若要对只有一个字节的字符串进行编码,如“3”,则在其编码结果的后面加“”,即“z”。
2、编码和解码
在JAVA中要实现Base64的编码和解码是非常容易的,因为JDK中已经有提供有现成的类:
编码:
String src ="BASE64编码测试";
sun.misc.BASE64Encoder en = new sun.misc.BASE64Encoder();
String encodeStr = en.encode(src.getBytes());
解码:
sun.misc.BASE64Decoder dec = newsun.misc.BASE64Decoder(); byte[] data = dec.decodeBuffer(decodeStr);
更多知识点参考请点击这里
filename = "=?UTF-8?B?"+new BASE64Encoder().encoder(filename.getBytes("utf-8"))+"?=";
BASE64Encoder 加密和解密
public class B64Demo {public static String getBASE64(String s) { if (s == null) return null; return (new sun.misc.BASE64Encoder()).encode(s.getBytes()); } // 将 BASE64 编码的字符串 s 进行解码public static String getFromBASE64(String s) { if (s == null) return null; sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder(); try { byte[] b = decoder.decodeBuffer(s); return new String(b); } catch (Exception e) { return null; } } // 将 BASE64 编码的字符串 s 进行加密,即对字符串进行三次的BASE64编码public static String encryption(Object obj){return B64Demo.getBASE64(B64Demo.getBASE64(B64Demo.getBASE64((String)obj)));}// 将 BASE64 编码的字符串 s 进行解密,即对字符串进行三次的BASE64解码public static String decryption(String 3b64){return B64Demo.getFromBASE64(B64Demo.getFromBASE64(B64Demo.getFromBASE64(3b64)));}public static void main(String[] args) {String a = encryption("100000.89".toString());System.out.println(a);//加密System.out.println(decryption(a));//解密}
}
一、jdk1.8下的 BASE64Encoder 和 BASE64Decoder(JDK9开始已移除):
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;public class test {public static void main(String[] args) throws Exception {String str = "hello word";BASE64Encoder base64Encoder = new BASE64Encoder();// JDK1.8 BASE64Encoder 加密String encode = base64Encoder.encode(str.getBytes());System.out.println(encode);BASE64Decoder base64Decoder = new BASE64Decoder();// JDK1.8 BASE64Decoder 解密byte[] bytes = base64Decoder.decodeBuffer(encode);String res = new String(bytes);System.out.println(res);}
}
二、推荐使用Base64:
package com.lmp.utils;import java.util.Base64;public class test {public static void main(String[] args) throws Exception {String str = "hello word";// JDK1.8 Base64加密String encode = Base64.getEncoder().encodeToString(str.getBytes());System.out.println(encode);// JDK1.8 Base64解密byte[] bytes = Base64.getDecoder().decode(encode);String res = new String(bytes);System.out.println(res);}}
Java中的Base64详解相关推荐
- Java中JDBC连接数据库详解
今天动力节点java学院小编分享的是JDBC连接数据库的相关知识,希望通过看过此文,各位小伙伴对DBC连接数据库有所了解,下面就跟随小编一起来看看JDBC连接数据库的知识吧. 一.JDBC连接数据库概 ...
- JAVA中的Random详解
JAVA中的Random详解 首先,在JDK自带的常用的random中有两个,这俩都是产生随机数的,不过一个是util下的random,另外一个是Math下的.我们分别介绍一下 util中的rando ...
- java中new关键字详解
java中new关键字详解 在java中我们可以经常使用new来创建一个对象,但是这对于初学者来说可能只会使用却不能理解new关键字和它的语法 new关键字的语法 注意使用前先导包,一般我们使用ide ...
- Java中super关键字详解
Java中super关键字详解 super有什么用? super什么时候不可以省略呢? super在内存图中是如何存在的呢? super使用时的注意事项 super有什么用? (1)当子类中构造方法第 ...
- Java中的byte详解
Java中的byte详解 介绍 byte,即字节,由8位的二进制组成.在Java中,byte类型的数据是8位带符号的二进制数. 在计算机中,8位带符号二进制数的取值范围是[-128, 127],所以在 ...
- Java中Iterator迭代器详解
目录 一.Java中Iterator迭代器详解 1.为什么需要迭代器 2.迭代器长什么样子 3.如何使用迭代器 使用步骤: 代码演示: 迭代器可以简化为增强型for循环: 4.Iterator与Lis ...
- Java 中IO流详解(附实例代码/面试题)
Java I/O流详解 前言 一.I/O流是什么? 二.IO流分类: 1. 流程图: io流对象 2. io流的优缺点: 3. io 流Java中用途有哪些? 三.一些 io 实例 四.面试题: 前言 ...
- 【转载】java中泛型使用详解
引入 Type接口 Class类 Method类 Field类 ParameterizedType接口 TypeVariable接口 类中定义泛型变量 方法中定义泛型变量 方法中泛型参数和泛型返回值 ...
- java 中的vector_详解Java中的Vector
Vector实现了AbstractList抽象类和List接口,和ArrayList一样是基于Array存储的 Vector 是线程安全的,在大多数方法上存在synchronized关键字 //Vec ...
最新文章
- codevs 2494 Vani和Cl2捉迷藏
- idea ssm框架 mysql_IDEA 2017 整合SSM框架(使用Maven创建工程)
- python批量删除_Python批量删除只保留最近几天table的代码实例
- 搭建ssm中遇到的问题
- 手机上如何免费压缩JPG
- 计算机复试面试基础知识(八股文)(数据库、数据结构、操作系统、计网、机组等)
- 子网掩码最简单通俗的解释
- Subversion vs Subclipse
- 天才女博士事迹引发的感想
- KeyUp 和KeyDown 、KeyPress之间的区别
- oracle直截取汉字,ORACLE_从字符串中提取汉字(不包括全角符及日文韩文等字符) | 学步园...
- 区块链入门者的五本必读书籍
- 擎天架构加持,华为云Stack打算在混合云市场怎么打?
- 怎么提高代码质量?-来自Google的研发经验总结
- Dataset之mpg:mpg汽车油耗数据集的简介、下载、使用方法之详细攻略
- Sybase ASE 15.5 利用自带scripts脚本创建演示数据库pubs2
- Linux高级应用(十三)按键控制
- EQ笔记1-什么叫均衡器-百度百科 转载
- Hadoop HA 高可用集群启动报错 Encountered exception loading fsimage 解决方案
- vue中的target与currentTarget区别