/** * Base64Util for Java * cheungmine * 2009-11-8 */ public class Base64Util { /** * @param args */ public static void main(String[] args) { // 源字节数组 int cb = 0; System.out.print("源字节数组: "); byte in[] = new byte[100]; in[cb++]='1'; in[cb++]='2'; in[cb++]='3'; in[cb++]='4'; in[cb++]='5'; System.out.write(in, 0, cb); // 计算编码需要的输出字节尺寸 int cbOut = encodeString( in, cb, null, 0); // 为输出分配数组 byte out[] = new byte[cbOut]; // 开始编码 encodeString( in, cb, out, 0); // 输出编码内容 System.out.print("/n编码后内容: "); System.out.write(out, 0, cbOut); // 计算解码需要的字节 int cbDec = decodeString(out, cbOut, null); // 分配解码数组 byte dec[] = new byte[cbDec]; // 开始解码 decodeString(out, cbOut, dec); // 输出解码结果, 这个结果和输出应该一致 System.out.print("/n解码的结果: "); System.out.write(dec, 0, cbDec); } /** * Translation Table as described in RFC1113 */ static String cb64="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * Translation Table to decode (created by author) */ static String cd64="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[//]^_`abcdefghijklmnopq"; /** * encodeBlock * * encode 3 8-bit binary bytes (in) as 4 '6-bit' characters (out) */ static void encodeBlock( byte in[], byte out[], int len ) { out[0] = (byte) cb64.charAt( in[0] >> 2 ); out[1] = (byte) cb64.charAt( ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ); out[2] = (byte) (len > 1 ? cb64.charAt( ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ) : '='); out[3] = (byte) (len > 2 ? cb64.charAt( in[2] & 0x3f ) : '='); } /** * decodeBlock * * decode 4 '6-bit' characters into 3 8-bit binary bytes */ static void decodeBlock( byte in[], byte out[] ) { out[ 0 ] = (byte) (in[0] << 2 | in[1] >> 4); out[ 1 ] = (byte) (in[1] << 4 | in[2] >> 2); out[ 2 ] = (byte) (((in[2] << 6) & 0xc0) | in[3]); } /** * encodeString * * base64 encode bytes * by cheungmine * outstr is allocated by caller * length of encoded string is returned (not including end closing '/0') */ public static int encodeString( byte instr[], int inlen, byte outstr[], int linesize ) { byte in[] = new byte[3]; byte out[]= new byte[4]; int inc=0, outc=0, i, len, blocksout = 0; /* only size of buffer required */ if (outstr==null){ if (linesize==0) return (inlen%3==0)? ((inlen/3)*4):((inlen/3+1)*4); while(inc < inlen) { len = 0; for( i = 0; i < 3; i++ ) { if (inc < inlen){ len++; inc++; } } if( len>0 ) { outc += 4; blocksout++; } if( blocksout >= (linesize/4) || inc==inlen ) { if( blocksout>0 ) { outc += 2; } blocksout = 0; } } return outc; } /* actual encoding below */ while(inc < inlen) { len = 0; for( i = 0; i < 3; i++ ) { if (inc < inlen){ len++; in[i] = instr[inc++]; } else{ in[i] = 0; // padding with zero } } if(len > 0) { encodeBlock( in, out, len ); for( i = 0; i < 4; i++ ) { outstr[outc++] = out[i]; } blocksout++; } if (linesize > 0){ if( blocksout >= (linesize/4) || inc==inlen ) { if(blocksout > 0) { outstr[outc++] = '/r'; outstr[outc++] = '/n'; } blocksout = 0; } } } return outc; } /** * add by cheungmine * 2009-11-1 */ public static int decodeString( byte instr[], int inlen, byte outstr[] ) { byte in[]=new byte[4]; byte out[]=new byte[3]; byte v; int inc=0, outc=0, i, len; /* only size of buffer required */ if (outstr==null){ while( inc < inlen ) { for( len = 0, i = 0; i < 4 && inc<inlen; i++ ) { v = 0; while( (inc<=inlen) && (v==0) ) { v = (inc < inlen)? instr[inc] : 0; inc++; v = (byte) ((v < 43 || v > 122) ? 0 : cd64.charAt(v-43)); if( v>0 ) { v = (byte) ((v == '$') ? 0 : v - 61); } } if( inc<=inlen ) { len++; } } if( len>1 ) { outc += (len-1); } } return outc; } while( inc < inlen ) { for( len = 0, i = 0; i < 4 && inc<inlen; i++ ) { v = 0; while( (inc<=inlen) && (v==0) ) { v = (inc < inlen)? instr[inc] : 0; inc++; v = (byte) ((v < 43 || v > 122) ? 0 : cd64.charAt(v-43)); if( v>0 ) { v = (byte) ((v == '$') ? 0 : v - 61); } } if( inc<=inlen ) { len++; if( v>0 ) { in[ i ] = (byte) (v - 1); } } else { in[i] = 0; } } if( len>0 ) { decodeBlock( in, out ); for( i = 0; i < len - 1; i++ ) { outstr[outc++] = out[i]; } } } return outc; } }