俊星的BLOG

JAVA MAIL之BASE64编码解码

关于BASE64编码,建议参看WIKI中的相关说明。
1、编码:

    public static byte[] base64encode(byte[] inbuf) {
        
int size = inbuf.length;
        
byte[] outbuf = new byte[((inbuf.length + 2) / 3) * 4];
        
int inpos, outpos;
        
int val;
        
// 情况1:大于等于3
        for (inpos = 0, outpos = 0; size >= 3; size -= 3, outpos += 4) {
            val 
= inbuf[inpos++] & 0xff;
            val 
<<= 8;
            val 
|= inbuf[inpos++] & 0xff;
            val 
<<= 8;
            val 
|= inbuf[inpos++] & 0xff;
            
// 到此val中存储了3*8=24个二进制位,然后分4次,每次6个二进制位输出
            outbuf[outpos + 3] = (byte) pem_array[val & 0x3f];
            val 
>>= 6;
            outbuf[outpos 
+ 2] = (byte) pem_array[val & 0x3f];
            val 
>>= 6;
            outbuf[outpos 
+ 1] = (byte) pem_array[val & 0x3f];
            val 
>>= 6;
            outbuf[outpos 
+ 0] = (byte) pem_array[val & 0x3f];
        }

        
// 情况2:等于1或者等于2
        if (size == 1) {
            val 
= inbuf[inpos++] & 0xff;
            val 
<<= 4;
            
// 到此val中实际有效二进制位8+4=12个,并且后4个都为0
            outbuf[outpos + 3] = (byte) '='; // pad character;
            outbuf[outpos + 2] = (byte) '='; // pad character;
            outbuf[outpos + 1] = (byte) pem_array[val & 0x3f];
            val 
>>= 6;
            outbuf[outpos 
+ 0] = (byte) pem_array[val & 0x3f];
        }
 else if (size == 2) {
            val 
= inbuf[inpos++] & 0xff;
            val 
<<= 8;
            val 
|= inbuf[inpos++] & 0xff;
            val 
<<= 2;
            
// 得到此val中实际有效二进制位为8+8+2=18个,并且后2个为0
            outbuf[outpos + 3] = (byte) '='; // pad character;
            outbuf[outpos + 2] = (byte) pem_array[val & 0x3f];
            val 
>>= 6;
            outbuf[outpos 
+ 1] = (byte) pem_array[val & 0x3f];
            val 
>>= 6;
            outbuf[outpos 
+ 0] = (byte) pem_array[val & 0x3f];
        }

        
return outbuf;
    }


    
private final static char pem_array[] = { 
            
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0
            'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2
            'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4
            'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5
            'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6
            '4', '5', '6', '7', '8', '9', '+', '/' // 7
    }
;

测试:
    public static void main(String[] args) {
        String [] strs 
= {"leasure.","easure.","asure.","sure."};
        
for(String str:strs){
            System.out.println(
new String(base64encode(str.getBytes())));
        }

    }

输出:
bGVhc3VyZS4=
ZWFzdXJlLg
==
YXN1cmUu
c3VyZS4
=

2、反编码:
    public static byte[] base64decode(byte[] inbuf) {
        
int size = (inbuf.length / 4) * 3;
        
if (inbuf[inbuf.length - 1] == '=') {
            size
--;
            
if (inbuf[inbuf.length - 2] == '=')
                size
--;
        }

        
byte[] outbuf = new byte[size];

        
int inpos = 0, outpos = 0;
        size 
= inbuf.length;
        
while (size > 0) {
            
int val;
            
int osize = 3;
            val 
= pem_convert_array[inbuf[inpos++] & 0xff];
            val 
<<= 6;
            val 
|= pem_convert_array[inbuf[inpos++] & 0xff];
            val 
<<= 6;
            
if (inbuf[inpos] != '=') // End of this BASE64 encoding
                val |= pem_convert_array[inbuf[inpos++] & 0xff];
            
else
                osize
--;
            val 
<<= 6;
            
if (inbuf[inpos] != '=') // End of this BASE64 encoding
                val |= pem_convert_array[inbuf[inpos++] & 0xff];
            
else
                osize
--;
            
if (osize > 2)
                outbuf[outpos 
+ 2] = (byte) (val & 0xff);
            val 
>>= 8;
            
if (osize > 1)
                outbuf[outpos 
+ 1] = (byte) (val & 0xff);
            val 
>>= 8;
            outbuf[outpos] 
= (byte) (val & 0xff);
            outpos 
+= osize;
            size 
-= 4;
        }

        
return outbuf;
    }


    
private final static char pem_array[] = { 
            
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0
            'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1
            'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2
            'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3
            'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4
            'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5
            'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6
            '4', '5', '6', '7', '8', '9', '+', '/' // 7
    }
;

    
private final static byte pem_convert_array[] = new byte[256];

    
static {
        
// 将数组中的每个元素的所有二进制位均初始化为1
        for (int i = 0; i < 255; i++)
            pem_convert_array[i] 
= -1;
        for (int i = 0; i < pem_array.length; i++)
            pem_convert_array[pem_array[i]] 
= (byte) i;
    }

测试:
    public static void main(String[] args) {
        String strs[] 
= { "bGVhc3VyZS4=", "ZWFzdXJlLg==", "YXN1cmUu", "c3VyZS4=" };
        
for(String str:strs){
            System.out.println(
new String(base64decode(str.getBytes())));
        }

    }

输出:
leasure.
easure.
asure.
sure.

posted on 2009-04-23 23:29 俊星 阅读(812) 评论(0)  编辑  收藏 所属分类: 代码库