2011-10-03

以 Java 實作 Base 64 Encoder

或許有人會覺得奇怪,Java 本身已經有支援 Base 64 Encoder 了,為什麼還要自己重新寫一個? 事實上,Java 平台的 Base64Encoder 需要 import sun.misc.BASE64Encoder,然而這個類別卻不是在所有平台上面都可以正常執行(我個人的經驗是,在 android 執行時會當機)。 以下為 Base 64 Encoder 實作程式碼,歡迎各位朋友切磋學習。
private static String base64_encode( byte[] bytes ) {
        String[] base64 = { "A", "B", "C", "D", "E", "F", "G", "H",
                            "I", "J", "K", "L", "M", "N", "O", "P",
                            "Q", "R", "S", "T", "U", "V", "W", "X",
                            "Y", "Z", "a", "b", "c", "d", "e", "f",
                            "g", "h", "i", "j", "k", "l", "m", "n",
                            "o", "p", "q", "r", "s", "t", "u", "v",
                            "w", "x", "y", "z", "0", "1", "2", "3",
                            "4", "5", "6", "7", "8", "9", "+", "/" };
        String encoded = "";

        int pad_length = 0;
        if ( bytes.length % 3 == 1 )
            pad_length = 2;
        else if ( bytes.length % 3 == 2 )
            pad_length = 1;
        
        byte[] padded = new byte[ bytes.length + pad_length ];

        for( int i = 0; i < bytes.length; ++i ) {
            padded[ i ] = bytes[ i ];
        }
        if ( pad_length == 1 ) {
            padded[ padded.length - 1 ] = 0;
        } else if ( pad_length == 2 ) {
            padded[ padded.length - 1 ] = 0;
            padded[ padded.length - 2 ] = 0;
        }
        
        for( int i = 0; i < padded.length; i += 3 ) {
            encoded += base64[ ( ( padded[ i ] & 255 ) >>> 2 ) ];
            encoded += base64[ ( ( ( padded[ i ] & 3 ) << 4 ) | ( ( padded[ i + 1 ] & 255 ) >>> 4 )  ) ];
            encoded += base64[ ( ( ( padded[ i + 1 ] & 15 ) << 2 ) | ( ( padded[ i + 2 ] & 255 ) >>> 6 )  ) ];
            encoded += base64[ ( padded[ i + 2 ] & 63 ) ];
        }
        
        encoded = encoded.substring( 0, encoded.length() - pad_length );
        
        if ( pad_length == 1 ) {
            encoded += "=";
        } else if ( pad_length == 2 ) {
            encoded += "==";
        }

        return encoded;
    }