Base64是网络上最常见的用于加密传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。
应该很清楚了吧?上面的三个字节是原文,下面的四个字节是转换后的Base64编码,其前两位均为0。 |
转换后,我们用一个码表来得到我们想要的字符串(也就是最终的Base64编码),这个表是这样的:(摘自RFC2045)
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
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
让我们再来看一个实际的例子,加深印象!
转换前 | 10101101 | 10111010 | 01110110 | |
转换后 | 00101011 | 00011011 | 00101001 | 00110110 |
十进制 | 43 | 27 | 41 | 54 |
对应码表中的值 | r | b | p | 2 |
所以上面的24位编码,编码后的Base64值为 rbp2
解码同理,把 rbq2 的二进制位连接上再重组得到三个8位值,得出原码。
(解码只是编码的逆过程,在此我就不多说了,另外有关MIME的RFC还是有很多的,如果需要详细情况请自行查找。)
下面的Base64编码/解码程序来自网上。
一、用SUN的API解码和编码
import java.io.*; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class Base64 { public static void main(String[] args) { if (args.length == 2) { String string = Base64.encode(args[0]); Base64.decode(string, args[1]); } else System.out.println("usage: java Base64 inputFile outputFile"); } public static String encode(String fileName) { String string = null; try { InputStream in = new FileInputStream(fileName); // in.available()返回文件的字节长度 byte[] bytes = new byte[in.available()]; // 将文件中的内容读入到数组中 in.read(bytes); string = new BASE64Encoder().encode(bytes); in.close(); } catch (FileNotFoundException fe) { fe.printStackTrace(); } catch(IOException ioe) { ioe.printStackTrace(); } return string; } public static void decode(String string, String fileName) { try { // 解码,然后将字节转换为文件 byte[] bytes = new BASE64Decoder().decodeBuffer(string); ByteArrayInputStream in = new ByteArrayInputStream(bytes); byte[] buffer = new byte[1024]; FileOutputStream out = new FileOutputStream(fileName); int bytesum = 0; int byteread = 0; while ((byteread = in.read(buffer)) != -1) { bytesum += byteread; out.write(buffer, 0, byteread); } } catch(IOException ioe) { ioe.printStackTrace(); } } }二、
/* @author CuCuChen * @version $Id$ */ import java.io.*; class Base64Helper {
//从文本文件对象中读取内容并转换为字符数组 public static char[] readChars(File file) { CharArrayWriter caw = new CharArrayWriter(); try { Reader fr = new FileReader(file); Reader in = new BufferedReader(fr); int count = 0; char[] buf = new char[16384]; while ((count=in.read(buf)) != -1) { if (count > 0) caw.write(buf, 0, count); } in.close(); } catch (Exception e) { e.printStackTrace(); } return caw.toCharArray(); }
//从字符串对象中读取内容并转换为字符数组 public static char[] readChars(String string) { CharArrayWriter caw = new CharArrayWriter(); try { Reader sr = new StringReader(string.trim()); Reader in = new BufferedReader(sr); int count = 0; char[] buf = new char[16384]; while ((count=in.read(buf)) != -1) { if (count > 0) caw.write(buf, 0, count); } in.close(); } catch (Exception e) { e.printStackTrace(); } return caw.toCharArray(); }
//从二进制文件对象中读取内容并转换为字节数组 public static byte[] readBytes(File file) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try { InputStream fis = new FileInputStream(file); InputStream is = new BufferedInputStream(fis); int count = 0; byte[] buf = new byte[16384]; while ((count=is.read(buf)) != -1) { if (count > 0) baos.write(buf, 0, count); } is.close(); } catch (Exception e) { e.printStackTrace(); } return baos.toByteArray(); }
//写字节数组内容到二进制文件 public static void writeBytes(File file, byte[] data) { try { OutputStream fos = new FileOutputStream(file); OutputStream os = new BufferedOutputStream(fos); os.write(data); os.close(); } catch (Exception e) { e.printStackTrace(); } } //写字符数组内容到文本文件 public static void writeChars(File file, char[] data) { try { Writer fos = new FileWriter(file); Writer os = new BufferedWriter(fos); os.write(data); os.close(); } catch (Exception e) { e.printStackTrace(); } } } public class Base64{ //编码文件对象所指的文件 static public char[] encode(File file){ if (!file.exists()) { System.err.println("错误:文件不存在!"); return null; } return encode(Base64Helper.readBytes(file)); }
//编码文件名所指的文件 static public char[] encode(String filename){ File file = new File(filename); if (!file.exists()) { System.err.println("错误:文件“"+filename+"”不存在!"); return null; } return encode(Base64Helper.readBytes(file)); } //编码传入的字节数组,输出编码后的字符数组 static public char[] encode(byte[] data) { char[] out = new char[((data.length + 2) / 3) * 4]; // // 对字节进行Base64编码,每三个字节转化为4个字符. // 输出总是能被4整除的偶数个字符 // for (int i=0, index=0; i< data.length; i+=3, index+=4) { boolean quad = false; boolean trip = false; int val = (0xFF & (int) data[i]); val <<= 8; if ((i+1) < data.length) { val |= (0xFF & (int) data[i+1]); trip = true; } val <<= 8; if ((i+2) < data.length) { val |= (0xFF & (int) data[i+2]); quad = true; } out[index+3] = alphabet[(quad? (val & 0x3F): 64)]; val >>= 6; out[index+2] = alphabet[(trip? (val & 0x3F): 64)]; val >>= 6; out[index+1] = alphabet[val & 0x3F]; val >>= 6; out[index+0] = alphabet[val & 0x3F]; } return out; } static public byte[] decode(char[] data) { // 程序中有判断如果有回车、空格等非法字符,则要去掉这些字符 // 这样就不会计算错误输出的内容 int tempLen = data.length; for( int ix=0; ix< data.length; ix++ ) { if( (data[ix] > 255) || codes[ data[ix] ] < 0 ) --tempLen; // 去除无效的字符 } // 计算byte的长度 // -- 每四个有效字符输出三个字节的内容 // -- 如果有额外的3个字符,则还要加上2个字节, // 或者如果有额外的2个字符,则要加上1个字节 int len = (tempLen / 4) * 3; if ((tempLen % 4) == 3) len += 2; if ((tempLen % 4) == 2) len += 1; byte[] out = new byte[len]; int shift = 0; int accum = 0; int index = 0; // 一个一个字符地解码(注意用的不是tempLen的值进行循环) for (int ix=0; ix< data.length; ix++) { int value = (data[ix]>255)? -1: codes[ data[ix] ]; if ( value >= 0 ) // 忽略无效字符 { accum <<= 6; shift += 6; accum |= value; if ( shift >= 8 ) { shift -= 8; out[index++] = (byte) ((accum >> shift) & 0xff); } } } //如果数组长度和实际长度不符合,那么抛出错误 if( index != out.length) { throw new Error("数据长度不一致(实际写入了 " + index + "字节,但是系统指示有" + out.length + "字节)"); } return out; } // // 用于编码的字符 // static private char[] alphabet ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray(); // // 用于解码的字节(0-255) // static private byte[] codes = new byte[256]; static { for (int i=0; i<256; i++) codes[i] = -1; for (int i = 'A'; i <= 'Z'; i++) codes[i] = (byte)( i - 'A'); for (int i = 'a'; i <= 'z'; i++) codes[i] = (byte)(26 + i - 'a'); for (int i = '0'; i <= '9'; i++) codes[i] = (byte)(52 + i - '0'); codes['+'] = 62; codes['/'] = 63; } public static void main (String [] args){ String key = new String("Spider"); byte[] a = key.getBytes(); char[] b = Base64.encode(a) ; System.out.println(new String(b)); //for(int i=0;i< b.length;i++){ // System.out.println(b[i]); //} byte[] c = Base64. decode(b); System.out.println(new String(c)); } } 运行结果: C:/java>java Base64
U3BpZGVy
Spider
转自:http://www.java3z.com/cwbwebhome/article/article2/2407.html?id=1095