在 Java 中如何进行 BASE64 编码和解码(转)
BASE64 编码是一种常用的字符编码,在很多地方都会用到。JDK 中提供了非常方便的 BASE64Encoder 和 BASE64Decoder,用它们可以非常方便的完成基于 BASE64 的编码和解码。下面是本人编的两个小的函数,分别用于 BASE64 的编码和解码:
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
// 将 s 进行 BASE64 编码
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;
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(s);
return new String(b);
} catch (Exception e) {
return null;
}
}
使用报文摘要
Java中提供了计算报文摘要的另一个简单的方法,那就是使用java.security.MessageDigest类。下列代码片断显示了如何将MD5报文摘要算法(128位的摘要)应用到密码字符串:
MassageDigest md=
MessageDigest.getInstance("MD5");
md.update(originalPwd.getByetes());
byte[] digestedBytes=md.digest();
也使用报文摘要创建校验和、文本的唯一ID(也叫做数字指纹)。在签写ARJ文件会发生:校验和是根据ARJ文件的内容计算出来的,然后被加密,并且用base64的加密格式存放在manifest.mf文件中。base64是编码任意二进制数据的一种方法,得到的结果仅包含可打印字符(注意,base64编码数据占用的空间比转换前多三分之一)。由于报文摘要算法输出的结果是字节数组,可以使用base64编码将哈希字节转换成字符串,以便能将该字符串存放在数据库的varchar字段中。现在有许多base64编码器,但是最简单的方法是使用weblogic.jar库中的编码器:weblogic.apache.xerces.utils.Base64。该类的作用微乎其微,如下面的代码例子所示:
String digestedPwdString =
new String(Base64.encode(digestedPwdBytes));
import javax.mail.internet.*;
import java.security.*;
public String getEncodedHash(String clearText){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
OutputStream out = MimeUtility.encode(baos,"base64");
MessageDigest md = MessageDigest.getInstance("SHA");
if(clearText == null) clearText = "";
byte [] in = clearText.getBytes();
byte [] digested = md.digest(in);
out.write(digested);
out.close();
return new String(baos.toByteArray(), "ISO-8859-1");
}
JDK1.4中的sun.misc.BASE64Encoder1在编码的字节较长时,encode出来的字符窜会在中间插入\n\r, 用Weblogic带的BASE64Encoder没有加回车换行
完整的base64定义可见RFC-1421和RFC-2045。编码后的数据比原始数据略长,为原来的4/3。在电子邮件中,根据RFC822规定,每76个字符,还需要加上一个回车换行
一个BASE64的实现:
1 /**
2 * @author yovn
3 *
4 */
5 public class BASE64Encoder {
6
7 private static char[] codec_table = { 'A', 'B', 'C', 'D', 'E', 'F', 'G',
8 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
9 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
10 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
11 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6',
12 '7', '8', '9', '+', '/' };
13
14 public BASE64Encoder() {
15
16 }
17
18 public String encode(byte[] a) {
19 int totalBits = a.length * 8;
20 int nn = totalBits % 6;
21 int curPos = 0;// process bits
22 StringBuffer toReturn = new StringBuffer();
23 while (curPos < totalBits) {
24 int bytePos = curPos / 8;
25 switch (curPos % 8) {
26 case 0:
27 toReturn.append(codec_table[(a[bytePos] & 0xfc) >> 2]);
28 break;
29 case 2:
30
31 toReturn.append(codec_table[(a[bytePos] & 0x3f)]);
32 break;
33 case 4:
34 if (bytePos == a.length - 1) {
35 toReturn
36 .append(codec_table[((a[bytePos] & 0x0f) << 2) & 0x3f]);
37 } else {
38 int pos = (((a[bytePos] & 0x0f) << 2) | ((a[bytePos + 1] & 0xc0) >> 6)) & 0x3f;
39 toReturn.append(codec_table[pos]);
40 }
41 break;
42 case 6:
43 if (bytePos == a.length - 1) {
44 toReturn
45 .append(codec_table[((a[bytePos] & 0x03) << 4) & 0x3f]);
46 } else {
47 int pos = (((a[bytePos] & 0x03) << 4) | ((a[bytePos + 1] & 0xf0) >> 4)) & 0x3f;
48 toReturn.append(codec_table[pos]);
49 }
50 break;
51 default:
52 //never hanppen
53 break;
54 }
55 curPos+=6;
56 }
57 if(nn==2)
58 {
59 toReturn.append("==");
60 }
61 else if(nn==4)
62 {
63 toReturn.append("=");
64 }
65 return toReturn.toString();
66
67 }
68
69 }