Dict.CN 在線詞典, 英語學習, 在線翻譯

          都市淘沙者

          荔枝FM Everyone can be host

          統(tǒng)計

          留言簿(23)

          積分與排名

          優(yōu)秀學習網站

          友情連接

          閱讀排行榜

          評論排行榜

          用Base64編碼與解碼

          用Base64編碼與解碼

          ?

          ?

          下載源代 碼

          ?
          Base64是網絡上最常見的用于加密傳輸8Bit字節(jié)代碼的編碼方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的詳細規(guī)范。Base64要求把每三個8Bit的字節(jié)轉換為四個6Bit的字節(jié)(3*8 = 4*6 = 24),然后把6Bit再添兩位高位0,組成四個8Bit的字節(jié),也就是說,轉換后的字符串理論上將要比原來的長1/3。

          這樣說會不會太抽象了?不怕,我們來看一個例子:
          轉換前aaaaaabbccccddddeeffffff
          轉換后00aaaaaa00bbcccc00ddddee00ffffff

          ????應該很清楚了吧?上面的三個字節(jié)是原文,下面的四個字節(jié)是轉換后的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()返回文件的字節(jié)長度
                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 {
                // 解碼,然后將字節(jié)轉換為文件
                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(); }
          //從二進制文件對象中讀取內容并轉換為字節(jié)數組 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(); }
          //寫字節(jié)數組內容到二進制文件 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)); } //編碼傳入的字節(jié)數組,輸出編碼后的字符數組 static public char[] encode(byte[] data) { char[] out = new char[((data.length + 2) / 3) * 4]; // // 對字節(jié)進行Base64編碼,每三個字節(jié)轉化為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的長度 // -- 每四個有效字符輸出三個字節(jié)的內容 // -- 如果有額外的3個字符,則還要加上2個字節(jié), // 或者如果有額外的2個字符,則要加上1個字節(jié) 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的值進行循環(huán)) 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 + "字節(jié),但是系統(tǒng)指示有" + out.length + "字節(jié))"); } return out; } // // 用于編碼的字符 // static private char[] alphabet ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".toCharArray(); // // 用于解碼的字節(jié)(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

          posted on 2006-11-08 08:34 都市淘沙者 閱讀(1042) 評論(0)  編輯  收藏 所屬分類: Java Basic/Lucene/開源資料

          主站蜘蛛池模板: 阿荣旗| 左云县| 宿松县| 丹东市| 阜新市| 东丰县| 乌拉特后旗| 湖口县| 辽阳县| 临桂县| 海晏县| 松原市| 尉犁县| 合川市| 南宁市| 进贤县| 安龙县| 普陀区| 邵阳县| 三亚市| 蓬溪县| 泾川县| 安龙县| 德昌县| 泌阳县| 三亚市| 东阳市| 巴彦县| 平定县| 贺兰县| 南漳县| 枣阳市| 张家口市| 逊克县| 合阳县| 东丰县| 红河县| 万荣县| 孝感市| 麻阳| 澄迈县|