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个字符,所对应表如下:

img

​ 转换的时候,将三个byte的数据,先后放入一个24bit的缓冲区中,先来的byte占高位。数据不足3byte的话,于缓冲区中剩下的bit用0补足。然后,每次取出6个bit,按照其值选择
**ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/**中的字符作为编码后的输出。不断进行,直到全部输入数据转换完成。

如果最后剩下两个输入数据,在编码结果后加1个“=”;如果最后剩下一个输入数据,编码结果后加2个“=”;如果没有剩下任何数据,就什么都不要加,这样才可以保证资料还原的正确性。

编码后的数据比原始数据略长,为原来的4/3。无论什么样的字符都会全部被编码,因此不像Quoted-printable编码,还保留部分可打印字符。所以,它的可读性不如Quoted-printable编码!

img
​ M的Ascii码是77,前六位对应值为19,对应base64字符是T,如此类推。其它字符编码就可以自动转换得到!我们看看另外不是刚好是3个字节的情况!
img

代码示例

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 
  1. 以上一共是64个编码,这也是Base64名称的由来。
  2. 编码的编号(1-64)对应的是得出的新字节的十进制值。因此,上例中字符串“张3”经过编码后就成了字符串“1iUz”了。
  3. 若要对只有两个字节的字符串进行编码,如“张”,则在其编码结果的后面加“=”,即“1iU=”。
  4. 若要对只有一个字节的字符串进行编码,如“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"))+"?=";

img

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);}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/554764.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java程序执行Linux命令

java程序中要执行linux命令主要依赖2个类:Process和Runtime 首先看一下Process类: ProcessBuilder.start() 和 Runtime.exec 方法创建一个本机进程,并返回 Process 子类的一个实例, 该实例可用来控制进程并获得相关信息。Proces…

ImageIO类说明

最近的项目中遇到ImageIO,因此记录下这个类的用法 一、ImageIO: 这个类中的方法都是静态方法,可以用来进行简单的图片IO操作 1、读入的三种方法 public static BufferedImage read(File input) File file new File("/Users/xixi/Docum…

java:图像(BufferedImage)色彩空间转换(灰度)暨获取图像矩阵数据byte[](sRGB/gray)

ColorConvertOp java.awt.image包下面有个类java.awt.image.ColorConvertOp,类名直译就是”颜色转换操作”。 顾名思义,它的作用就是将一个色彩空间(color space)的图像转换为另一个色彩空间的图像。有了这个神器我们就能轻易的将一张彩色图你像转换成灰度(gray)或其他色彩空间…

MyBatis-Plus updateById方法更新不了空字符串/null解决方法

最近遇到了Mybatis-Plus updateById(),更新某一个字段为null,却发现没有更新成功。记录一下 一、简介 因为最近在忙项目,好久都没有更新博客,最近在项目中刚好遇到一个问题,就是在使用MyBatis-Plus updateById&#…

Java 分割字符串的方法String.split()底层原理与使用

文章目录split()底层原理1.举例说明2.split源码分析3.API原解4.regex参数API原解5.limit参数介绍6.结果的验证7.此方法的使用split方法的使用split用法分析参数解释—regex参数解释—limit不同limit值的情况下的split结果验证扩展split()底层原理 1.举例说明 1.最普通的用法 …

MySQL中数据类型的长度问题解析

MySQL中数据类型的长度问题总结 1):int类型,对吧,经常像保存个时间戳啊、id啊、数量啊、排序啊都会用到 提问:INT(11)是什么意思?最大保存十一位数么? 回答:…

HttpComponents入门解析

1 简介 超文本传输协议(http)是目前互联网上极其普遍的传输协议,它为构建功能丰富,绚丽多彩的网页提供了强大的支持。构建一个网站,通常无需直接操作http协议,目前流行的WEB框架已经透明的将这些底层功能封装的很好了&#xff0c…

HttpClient使用和详解

文章目录一、关于HttpClient二、HttpClient使用步骤详解1、创建一个HttpClient对象A、HttpCLientConnectionManagerB、HttpRoutePlannerC、RequestConfig2、创建一个Request对象3、执行Request请求4、处理response1)关闭和entity相关的content stream2)关…

你还在 Docker 中跑 MySQL?

容器的定义:容器是为了解决“在切换运行环境时,如何保证软件能够正常运行”这一问题。 目前,容器和 Docker依旧是技术领域最热门的词语,无状态的服务容器化已经是大势所趋,同时也带来了一个热点问题被大家所争论不以&…

使用mybatis-plus来自定义排序

需求&#xff1a; 先时间升序排序&#xff0c;相同的时间在按状态排序&#xff0c;状态的顺序为1 在线 4 潜伏 2 隐身 3 离开&#xff0c;状态相同在按姓名升序排序对排序好的数据进行分页运用mybatis-plus中QueryWrapper 1.导入依赖 <dependencies><dependency>…

Postman实现接口测试(附项目实战)

文章目录Postman实现接口测试1.Postman介绍和安装2. Postman安装2.1 安装方式2.2 安装步骤3. Postman入门示例Postman基本用法Postman高级用法1. 管理用例2. Postman断言3. 全局变量与环境变量5. Postman关联6. 批量执行测试用例7. 读取外部文件实现参数化Postman测试报告目标项…

Postman 使用教程详解

Postman页面 2、新建一个项目 直接点击左边栏上面的添加目录图标来新增一个根目录&#xff0c;这样就等于新建了一个项目&#xff0c;我们可以把一个项目或一个模块的用例都存放在这个目录之下&#xff0c;并且在根目录之下我们还可以在建立子目录来进行功能用例的细分&#…

聊聊@Autowired注解注入,写接口名字还是实现类的名字

用Autowired注解注入,写接口名字还是实现类的名字 来自某程序员一个问答问题 有一点没明白&#xff0c;为什么注解repository注解的是接口UserDAO的实现类UserDAOImpl&#xff0c;而在UserServiceImpl中使用Autowired注解注入属性private UserDAO userDAO自动装配&#xff0c…

Spring注入接口还是实现类,同一接口有多个实现类,如何注入

1、接口&#xff1a;IUserService public interface IUserService {public void sayHello(); }2、实现类&#xff1a;UserServiceImpl&#xff0c;实现了UserService接口 Service("UserServiceImpl ") public class UserServiceImpl implements IUserService{// 添…

Spring只能注入接口,不能注入实现类

只能注入接口&#xff0c;不能注入实现类。 Controller public class Test {AutowiredprivateRoleDao rdi; }privateRoleDao是个接口 这样注入就没有问题&#xff0c; 而注入 Controller public class Test {AutowiredprivateRoleDaoImpl rdi; }会报错&#xff1a;No qua…

调用Dubbo报错: com.alibaba.dubbo.rpc.RpcException: Failed to invoke the method 问题原因和解决办法

我们在使用Dubbo的过程中&#xff0c;时常会碰到这个异常。而有可能导致这个异常的原因是非常多的&#xff0c;排查起来比较困难。下面把如何排查该问题的思路整理了一下&#xff0c;目前我知道的会导致这个异常的原因分为以下几类&#xff1a; 1.需要进行序列化的POJO类没有进…

Springboot dubbo @Service @Transactional 无法提供服务或者无法提供事务的解决办法

问题场景&#xff1a; 今天在springboot中集成spring事务的时候&#xff0c;遇到了一个大坑。如果&#xff08;springbootdubbo&#xff09;中添加 Service、Transactional 两个注解的时候&#xff0c;就不能进行dubbo服务注册了。 解决历程&#xff1a; 1&#xff0c;先是在…

Dubbo序列化

Dubbo序列化 dubbo作为一个rpc框架支持丰富的序列化方式&#xff0c;本文简单介绍dubbo的序列化。本文结构&#xff1a; 对象序列化是什么意思&#xff1f;dubbo序列化几个问题 对象序列化是什意思&#xff1f; 先来思考两个问题&#xff1a; 普通的Java对象的生命周期是仅…

什么是 serialVersionUID ? 序列化对象时必须提供 serialVersionUID 吗?

什么是 serialVersionUID &#xff1f; 序列化对象时必须提供 serialVersionUID 吗&#xff1f; 1&#xff0c;什么是 serialVersionUID &#xff1f; 顾名思义&#xff0c;serialVersionUID是序列化版本号。所有可序列化的类&#xff0c;都有一个静态serialVersionUID属性&a…

【Dubbo学习系列】Dubbo消费端的代理生成详解(@DubboReference和@Reference)

文章目录Spring中Dubbo实现RPC如何加载Reference和DubboReference注解DubboComponentScanRegistrar概括发现Refrence和DubboReference注解&#xff0c;并编织RPC通信逻辑ReferenceAnnotationBeanPostProcessor&#xff08;核心&#xff09;ReferenceDubboReferenceReference和D…