什么,Base64 算法你用的哪个?不就一种算法实现吗
2017-01-14 18:37
531 查看
什么,Base64 算法你用的哪个?不就一种算法实现吗
Base64算法最早主要是解决电子邮件的传输问题,由于当时的网关有个问题就是可能会使非ASCII码字符的二进制位做调整,导致用户收取的邮件变成乱码,所以就出现了Base64算法。算法思想见:https://zh.wikipedia.org/wiki/Base64 。
经过Base64编码后的数据会比原始数据长点,为原来的4/3倍。经过Base64编码后的字符串的字符数是以4为单位的整数倍。
RFC2045还规定,在电子邮件中,每行为76个字符,每行末需添加一个回车换行符(“\r\n”),无论每行是否够76个字符,都要添加一个回车换行符,但算法的实现不一定是这样做的。
Base64算法的实现:
1. JDK8代码:
import java.nio.charset.StandardCharsets; import java.util.Base64; /** * @author sdcuike * * Created At 2017年1月14日 下午5:05:44 */ public class JdkBase64 { public static void main(String[] args) { String plainText = "Base64算法最早主要是解决电子邮件的传输问题," + "由于当时的网关有个问题就是可能会度非ASCII码字符的二进制位做调整," + "导致用户收取的邮件变成乱码,所以就出现了Base64算法"; String base64String = Base64.getEncoder().encodeToString(plainText.getBytes(StandardCharsets.UTF_8)); System.out.println(base64String); System.out.println(new String(Base64.getDecoder().decode(base64String), StandardCharsets.UTF_8)); } }
代码结果:
QmFzZTY0566X5rOV5pyA5pep5Li76KaB5piv6Kej5Yaz55S15a2Q6YKu5Lu255qE5Lyg6L6T6Zeu6aKY77yM55Sx5LqO5b2T5pe255qE572R5YWz5pyJ5Liq6Zeu6aKY5bCx5piv5Y+v6IO95Lya5bqm6Z2eQVNDSUnnoIHlrZfnrKbnmoTkuozov5vliLbkvY3lgZrosIPmlbTvvIzlr7zoh7TnlKjmiLfmlLblj5bnmoTpgq7ku7blj5jmiJDkubHnoIHvvIzmiYDku6XlsLHlh7rnjrDkuoZCYXNlNjTnrpfms5U=
请注意:原文base64后并没有相应的回车换行(\r\n),也就是jdk8上面的方法并没有遵循RFC2045的定义。
上图红线位置,看到并没有出现回车换行符号。
debug状态下该字符串为:
QmFzZTY0566X5rOV5pyA5pep5Li76KaB5piv6Kej5Yaz55S15a2Q6YKu5Lu255qE5Lyg6L6T6Zeu6aKY77yM55Sx5LqO5b2T5pe255qE572R5YWz5pyJ5Liq6Zeu6aKY5bCx5piv5Y+v6IO95Lya5bqm6Z2eQVNDSUnnoIHlrZfnrKbnmoTkuozov5vliLbkvY3lgZrosIPmlbTvvIzlr7zoh7TnlKjmiLfmlLblj5bnmoTpgq7ku7blj5jmiJDkubHnoIHvvIzmiYDku6XlsLHlh7rnjrDkuoZCYXNlNjTnrpfms5U=
我们用另外一种方法:
base64String = Base64.getMimeEncoder().encodeToString(plainText.getBytes(StandardCharsets.UTF_8)); System.out.println(base64String); System.out.println(new String(Base64.getMimeDecoder().decode(base64String), StandardCharsets.UTF_8));
得到的结果:
QmFzZTY0566X5rOV5pyA5pep5Li76KaB5piv6Kej5Yaz55S15a2Q6YKu5Lu255qE5Lyg6L6T6Zeu\r\n
6aKY77yM55Sx5LqO5b2T5pe255qE572R5YWz5pyJ5Liq6Zeu6aKY5bCx5piv5Y+v6IO95Lya5bqm\r\n
6Z2eQVNDSUnnoIHlrZfnrKbnmoTkuozov5vliLbkvY3lgZrosIPmlbTvvIzlr7zoh7TnlKjmiLfm\r\n
lLblj5bnmoTpgq7ku7blj5jmiJDkubHnoIHvvIzmiYDku6XlsLHlh7rnjrDkuoZCYXNlNjTnrpfm\r\n
s5U=
编码后的字符串出现了相应了回车换行符号。
2.Apache Commons Codec 实现:
import java.nio.charset.StandardCharsets; import org.apache.commons.codec.binary.Base64; import com.google.common.base.Preconditions; /** * @author sdcuike * * Created At 2017年1月14日 下午6:01:21 */ public class CommonsCodecBase64 { public static void main(String[] args) { String plainText = "Base64算法最早主要是解决电子邮件的传输问题," + "由于当时的网关有个问题就是可能会度非ASCII码字符的二进制位做调整," + "导致用户收取的邮件变成乱码,所以就出现了Base64算法"; String base64String = Base64.encodeBase64String(plainText.getBytes(StandardCharsets.UTF_8)); System.out.println(base64String); String plainTxt = new String(Base64.decodeBase64(base64String), StandardCharsets.UTF_8); Preconditions.checkArgument(plainTxt.equals(plainText)); } }
结果:
QmFzZTY0566X5rOV5pyA5pep5Li76KaB5piv6Kej5Yaz55S15a2Q6YKu5Lu255qE5Lyg6L6T6Zeu6aKY77yM55Sx5LqO5b2T5pe255qE572R5YWz5pyJ5Liq6Zeu6aKY5bCx5piv5Y+v6IO95Lya5bqm6Z2eQVNDSUnnoIHlrZfnrKbnmoTkuozov5vliLbkvY3lgZrosIPmlbTvvIzlr7zoh7TnlKjmiLfmlLblj5bnmoTpgq7ku7blj5jmiJDkubHnoIHvvIzmiYDku6XlsLHlh7rnjrDkuoZCYXNlNjTnrpfms5U=
和jdk8的第一种实现一样的结果。
另一种方法:
// 出现回车换行符号 base64String = new String(Base64.encodeBase64Chunked(plainText.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); plainTxt = new String(Base64.decodeBase64(base64String), StandardCharsets.UTF_8); Preconditions.checkArgument(plainTxt.equals(plainText));
编码后的结果:
QmFzZTY0566X5rOV5pyA5pep5Li76KaB5piv6Kej5Yaz55S15a2Q6YKu5Lu255qE5Lyg6L6T6Zeu\r\n
6aKY77yM55Sx5LqO5b2T5pe255qE572R5YWz5pyJ5Liq6Zeu6aKY5bCx5piv5Y+v6IO95Lya5bqm\r\n
6Z2eQVNDSUnnoIHlrZfnrKbnmoTkuozov5vliLbkvY3lgZrosIPmlbTvvIzlr7zoh7TnlKjmiLfm\r\n
lLblj5bnmoTpgq7ku7blj5jmiJDkubHnoIHvvIzmiYDku6XlsLHlh7rnjrDkuoZCYXNlNjTnrpfm\r\n
s5U=\r\n
每76个字符出现回车换行,最后一行不满76个字符,也出现了回车换行,和jdk8实现的区别就在最后一行,看来JDK8的实现好像不太符合RFC2045标准,而Apache
Commons Codec 是我们工作中的首先使用库。
相关文章推荐
- Note07
- 巧用weui.gallery(),点击图片后预览图片
- Java的变量类型
- 学徒的时候安卓老知识点总结汇总 (新手应该大概了解的)
- hdu 1890 Robotic Sort(splay 区间反转+删点)
- gets和scanf输入字符串的比较
- 分析"今日头条"Android客户端所使用的开源技术
- 系统架构设计师教程知识整理——计算机与网络基础知识(二)
- JRE和JDK的区别及作用
- 来自何处
- FFmpeg截取视频生成高清Gif
- opencv学习(二十二)之双边滤波bilateralFilter
- 7 -- Spring的基本用法 -- 10... 获取其他Bean的属性值;获取Field值;获取任意方法的返回值
- 科技论文写作经验之谈
- 【C语言】模拟实现strcmp()、strncmp()函数
- (转)大数据的寒冬已至,谁将倒下,谁成巨人?
- 系统架构设计师教程知识整理——绪论(一)
- STC89C52串口应用实例
- 微信小程序开发之入门详解
- Kattis - Aaah!