您的位置:首页 > 其它

什么,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 是我们工作中的首先使用库。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: