代码之家  ›  专栏  ›  技术社区  ›  Ken

解码Base64字符串Java 5

  •  6
  • Ken  · 技术社区  · 16 年前

    是否有一种直接使用Java 1.5库来解码Base64字符串的方法?

    由于Windows和Mac OS X之间的跨平台兼容性问题,我不得不使用Java 1.5(只有MAC 10.5支持Java 1.6,低于10.5的任何东西都有Java 1.5作为默认值)。

    对象“Sun .MISC.Base64解码器”存在于Java 6中,但不存在于Java 5中。

    5 回复  |  直到 13 年前
        1
  •  9
  •   Jonathan Holloway    16 年前

    不,仅使用JDK5.0是不可能的。

    您需要滚动自己的实现(这并不难),或者最好使用一个开放源代码实现。有很多,包括提供base64的通用编解码器 http://commons.apache.org/codec/api-release/org/apache/commons/codec/binary/Base64.html

    Javamail还通过模拟提供base64编码/解码,也引用了可打印的编码等。

    http://java.sun.com/products/javamail/javadocs/javax/mail/internet/MimeUtility.html

        2
  •  8
  •   Jherico    16 年前

    Apache Commons Codec

    FYI,即使在Java 6中也应该使用它。 Don't use classes in sun.*

        3
  •  7
  •   MikeC Clint    13 年前

    只使用 http://iharder.sourceforge.net/current/java/base64/ . 它在公共领域。因此,您可以将代码放到项目中,而不必担心许可证问题或包括其他JAR。您要查找的类不在JDK 1.5中。

        4
  •  6
  •   L. Cornelius Dol    16 年前

    这是我的版本-它应该是完全独立的:

    public class Base64
    {
    
    // *****************************************************************************
    // INSTANCE PROPERTIES
    // *****************************************************************************
    
    private String                          lineSeparator;
    private int                             lineLength;
    
    // *****************************************************************************
    // INSTANCE CONSTRUCTION/INITIALIZATON/FINALIZATION, OPEN/CLOSE
    // *****************************************************************************
    
    public Base64() {
        lineSeparator=System.getProperty("line.separator");
        lineLength=0;
        }
    
    // *****************************************************************************
    // INSTANCE METHODS
    // *****************************************************************************
    
    public String encode(byte[] bin) {
        return encode(bin,0,bin.length);
        }
    /**
     * Encode an array of bytes as Base64.
     * It will be broken into lines if the line length is not 0.  If broken into lines,
     * the last line is not terminated with a line separator.
     *
     * param ba         The byte array to encode.
     */
    public String encode(byte[] bin, int str, int len) {
        int                                 ol;                                     // output length
        StringBuffer                        sb;                                     // string buffer for output(must be local for recursion to work).
        int                                 lp;                                     // line position(must be local for recursion to work).
        int                                 el;                                     // even multiple of 3 length
        int                                 ll;                                     // leftover length
    
        // CREATE OUTPUT BUFFER
        ol=(((len+2)/3)*4);
        if(lineLength!=0) {
            int lines=(((ol+lineLength-1)/lineLength)-1);
            if(lines>0) { ol+=(lines*lineSeparator.length()); }
            }
        sb=new StringBuffer(ol);
        lp=0;
    
        // EVEN MULTIPLES OF 3
        el=(len/3)*3;
        ll=(len-el);
        for(int xa=0; xa<el; xa+=3) {
            int cv;
            int c0,c1,c2,c3;
    
            if(lineLength!=0) {
                lp+=4;
                if(lp>lineLength) { sb.append(lineSeparator); lp=4; }
                }
    
            // get next three bytes in unsigned form lined up, in big-endian order
            cv =(bin[xa+str+0]&0xFF); cv<<=8;
            cv|=(bin[xa+str+1]&0xFF); cv<<=8;
            cv|=(bin[xa+str+2]&0xFF);
    
            // break those 24 bits into a 4 groups of 6 bits, working LSB to MSB.
            c3=cv&0x3F; cv >>>=6;
            c2=cv&0x3F; cv >>>=6;
            c1=cv&0x3F; cv >>>=6;
            c0=cv&0x3F;
    
            // Translate into the equivalent alpha character emitting them in big-endian order.
            sb.append(ENCODE[c0]);
            sb.append(ENCODE[c1]);
            sb.append(ENCODE[c2]);
            sb.append(ENCODE[c3]);
            }
    
        // LEFTOVERS
        if(lineLength!=0 && ll>0) {
            lp+=4;
            if(lp>lineLength) { sb.append(lineSeparator); lp=4; }
            }
        if(ll==1) {
            sb.append(encode(new byte[] { bin[el+str], 0, 0 }).substring(0,2)).append("==");            // Use recursion so escaping logic is not repeated, replacing last 2 chars with "==".
            }
        else if(ll==2) {
            sb.append(encode(new byte[] { bin[el+str], bin[el+str+1], 0 }).substring(0,3)).append("="); // Use recursion so escaping logic is not repeated, replacing last char and  "=".
            }
        if(ol!=sb.length()) { throw new RuntimeException("Error in Base64 encoding method: Calculated output length of "+ol+" did not match actual length of "+sb.length()); }
        return sb.toString();
        }
    
    public byte[] decode(String b64) {
        return decode(b64,0,b64.length());
        }
    
    /**
     * Decode a Base64 string to an array of bytes.
     * The string must have a length evenly divisible by 4 (not counting line separators and other
     * ignorable characters, like whitespace).
     */
    public byte[] decode(String b64, int str, int len) {
        byte[]                              ba;                                     // target byte array
        int                                 dc;                                     // decode cycle (within sequence of 4 input chars).
        int                                 rv;                                     // reconstituted value
        int                                 ol;                                     // output length
        int                                 pc;                                     // padding count
    
        ba=new byte[(len/4)*3];                                                     // create array to largest possible size.
        dc=0;
        rv=0;
        ol=0;
        pc=0;
    
        for(int xa=0; xa<len; xa++) {
            int ch=b64.charAt(xa+str);
            int value=(ch<=255 ? DECODE[ch] : IGNORE);
            if(value!=IGNORE) {
                if(value==PAD) {
                    value=0;
                    pc++;
                    }
                switch(dc) {
                    case 0: {
                        rv=value;
                        dc=1;
                        } break;
    
                    case 1: {
                        rv<<=6;
                        rv|=value;
                        dc=2;
                        } break;
    
                    case 2: {
                        rv<<=6;
                        rv|=value;
                        dc=3;
                        } break;
    
                    case 3: {
                        rv<<=6;
                        rv|=value;
    
                        // Completed a cycle of 4 chars, so recombine the four 6-bit values in big-endian order
                        ba[ol+2]=(byte)rv;  rv>>>=8;
                        ba[ol+1]=(byte)rv;  rv>>>=8;
                        ba[ol]=(byte)rv;    ol+=3;
                        dc=0;
                        } break;
                    }
                }
            }
        if(dc!=0) {
            throw new ArrayIndexOutOfBoundsException("Base64 data given as input was not an even multiple of 4 characters (should be padded with '=' characters).");
            }
        ol-=pc;
        if(ba.length!=ol) {
            byte[] b2=new byte[ol];
            System.arraycopy(ba, 0, b2, 0, ol);
            ba=b2;
            }
        return ba;
        }
    
    /**
    * Set maximum line length for encoded lines.
    * Ignored by decode.
    * @param len        Length of each line. 0 means no newlines inserted. Must be a multiple of 4.
    */
    public void setLineLength(int len) {
      this.lineLength=(len/4)*4;
      }
    
    /**
    * Set the line separator sequence for encoded lines.
    * Ignored by decode.
    * Usually contains only a combination of chars \n and \r, but could be any chars except 'A'-'Z', 'a'-'z', '0'-'9', '+' and '/'.
    * @param linsep     Line separator - may be "" but not null.
    */
    public void setLineSeparator(String linsep) {
      this.lineSeparator=linsep;
      }
    
    // *****************************************************************************
    // STATIC PROPERTIES
    // *****************************************************************************
    
    static private final char[]             ENCODE=new char[64];                    // translation array for encoding
    static private final int[]              DECODE=new int[256];                    // translation array for decoding
    static private final int                IGNORE=-1;                              // flag for values to ignore when decoding
    static private final int                PAD=-2;                                 // flag value for padding value when decoding
    
    static private final Base64             BASE64=new Base64();                    // default converter
    
    // *****************************************************************************
    // STATIC INIT & MAIN
    // *****************************************************************************
    
    static {
        for(int xa=0; xa<=25; xa++) { ENCODE[xa]=(char)('A'+xa); }                  //  0..25 -> 'A'..'Z'
        for(int xa=0; xa<=25; xa++) { ENCODE[xa+26]=(char)('a'+xa); }               // 26..51 -> 'a'..'z'
        for(int xa=0; xa<= 9; xa++) { ENCODE[xa+52]=(char)('0'+xa); }               // 52..61 -> '0'..'9'
        ENCODE[62]='+';
        ENCODE[63]='/';
    
        for(int xa=0; xa<256; xa++) { DECODE[xa]=IGNORE;     }                      // set all chars to IGNORE, first
        for(int xa=0; xa< 64; xa++) { DECODE[ENCODE[xa]]=xa; }                      // set the Base 64 chars to their integer byte values
        DECODE['=']=PAD;
        }
    
    // *****************************************************************************
    // STATIC METHODS
    // *****************************************************************************
    
    static public String toString(byte[] dta) {
        return BASE64.encode(dta);
        }
    
    static public String toString(byte[] dta, int str, int len) {
        return BASE64.encode(dta,str,len);
        }
    
    static public byte[] toBytes(String b64) {
        return BASE64.decode(b64);
        }
    
    static public byte[] toBytes(String b64, int str, int len) {
        return BASE64.decode(b64,str,len);
        }
    
    } // END PUBLIC CLASS
    
        5
  •  0
  •   Andre Miller    16 年前