JAVA BASE64

Base64编码说明:

    Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。 如果剩下的字符不足3个字节则用0填充,输出字符使用'=',因此编码后输出的文本末尾可能会出现1或2个'='

   为了保证所输出的编码位可读字符,Base64制定了一个编码表,以便进行统一转换。编码表的大小为2^6=64,这也是Base64名称的由来。

Base64编码表:

                                                             

package com.sunchao.base64;

/**
 * Base64
 * @author Administrator
 *
 */
public class Base64 {
    private static final byte[] CODE;
    private static final int[] BI;
    
    static{
        CODE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
                .getBytes();
        BI = new int['z' - '+' + 1];
        for(int i = 0; i < CODE.length; i++)
            BI[CODE[i] - 1] = i;
    }
    
    private static final int indexOf(byte b){
        int index = b - '+';
        return BI[index];
    }
    
    public static byte[] decode(byte[] base64){
            if(base64 == null) 
                throw new NullPointerException();
             
            if(base64.length < 4)
                throw new IllegalArgumentException("invalid base64 format!");
            
            int left = 0,right = (base64.length >> 2) * 3;
            int len = right;
            if(base64[base64.length-2] == '='){
                len = right - 2;
                right = base64.length-3;
            }else if(base64[base64.length-1] == '='){
                len = right - 1;
                right = base64.length-3;
            }
            final byte[] result = new byte[len];
             
            for(int i=left,j=0;i<right&&j<len;){
                int a = indexOf(base64[i++]);
                int b = indexOf(base64[i++]);
                int c = indexOf(base64[i++]);
                int d = indexOf(base64[i++]);
                byte aa = (byte)((a<<2)|((b>>4)&0xF));
                byte bb = (byte)(((b & 0xf)<<4)|((c>>2)&0x3F));
                byte cc = (byte)((c & 0x3)<<6 | d);
                 
                result[j++] = aa;
                 
                if(j >= len) 
                        break;
                result[j++] = bb;
                if(j >= len) 
                        break;
                result[j++] = cc;
            }  
            return result;
    }
    
    public static byte[] encode(byte[] data, int offset, int len){
        if(len == 0) return new byte[0];
        checkBounds(data.length, offset, len);
        int lp3 = len % 3;
        final byte[] result;
        
        if(lp3 == 0)
            result = new byte[(len / 3) * 4];
        else
            result = new byte[(len + 3 - lp3) / 3 * 4];
        
        int left = offset, right = offset + len - lp3, i = 0;
        
        for(;left < right;){
            byte a = data[left++];
            byte b = data[left++];
            byte c = data[left++];
            i = encode(a, b, c, i, result);
        }
        if(lp3 >= 1){
            int a = data[left++];
            result[i++] = CODE[(a >> 2) & 0x3f];
            int b = left<data.length?data[left++]:0;
            int c = left<data.length?data[left++]:0;
            result[i++] = CODE[(a & 3)<<4 | ((b>>4)&0xf)];
            if(lp3 == 2)
                result[i++] = CODE[(b & 0xf)<<2 | ((c>>6)&0x3)];
            else
                result[i++] = '=';
            result[i] = '=';
        }
        return result;    
    }
    
    private static int encode(byte a, byte b, byte c, int i, byte[] result){
         result[i++] = CODE[(a >> 2) & 0x3f];
         result[i++] = CODE[(a & 3) << 4 | ((b>>4) & 0xf)];
         result[i++] = CODE[(b & 0xf) << 2 | ((c>>6) & 0x3)];
         result[i++] = CODE[c & 0x3f];
         return i;
    }
    
    private static void checkBounds(int length, int offset, int charLen){
        if(offset < 0)  throw new IllegalArgumentException("Negative offset : " + offset);
        if(offset > length) throw new IndexOutOfBoundsException("offset over the length : "
                                                          + (offset - length));
        if(offset + charLen > length)  throw new IndexOutOfBoundsException("offser + charLen - length : "
                                                          + (offset + charLen - length));        
    }
}

 

posted @ 2015-05-22 15:39  TomSun*star  阅读(253)  评论(0编辑  收藏  举报