java Base64加密算法


1.Base64是什么:

Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一,大家可以查看RFC2045~RFC2049,上面有MIME的详细规范。Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。Base64编码是可逆的,知道加密后的内容,很容易就可以算出原文

2.简介:

标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符

为解决此问题,可采用一种用于URL的改进Base64编码,它不在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“*”和“-”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。

另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。

此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)。

Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。

3.规则:

关于这个编码的规则:

①.把3个字符变成4个字符..
.每76个字符加一个换行符..
③.最后的结束符也要处理..

4.实现

java有很多开源实现,java自身的库也有实现,java.util包和 sun.misc.都有实现。使用时只要注意返回的是byte[]还是字符串就可以了。
下面提供一种自己现实的源码:
package com.common.util.security;
import java.io.ByteArrayOutputStream;  
import java.io.IOException;  
import java.io.OutputStream; 

import sun.misc.BASE64Encoder;

public class Base64 {
	//BASE64编码的转换表  总长度63
	private static final char [] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" .toCharArray();  
    
    public static String encode( byte [] data) {  
        int start = 0 ;  
        int len = data.length;  
        StringBuffer buf = new StringBuffer(data.length * 3 / 2 );  
       
        int end = len - 3 ;  
        int i = start;  
        int n = 0 ;  
       
        while (i <= end) {  
            int d = (((( int ) data[i]) & 0x0ff ) << 16 ) | (((( int ) data[i + 1 ]) & 0x0ff ) << 8 ) | ((( int ) data[i + 2 ]) & 0x0ff );  
       
            buf.append(legalChars[(d >> 18 ) & 63 ]);  
            buf.append(legalChars[(d >> 12 ) & 63 ]);  
            buf.append(legalChars[(d >> 6 ) & 63 ]);  
            buf.append(legalChars[d & 63 ]);  
       
            i += 3 ;  
       
            if (n++ >= 14 ) {  
                n = 0 ;  
                buf.append( " " );  
            }  
        }  
       
        if (i == start + len - 2 ) {  
            int d = (((( int ) data[i]) & 0x0ff ) << 16 ) | (((( int ) data[i + 1 ]) & 255 ) << 8 );  
       
            buf.append(legalChars[(d >> 18 ) & 63 ]);  
            buf.append(legalChars[(d >> 12 ) & 63 ]);  
            buf.append(legalChars[(d >> 6 ) & 63 ]);  
            buf.append( "=" );  
        } else if (i == start + len - 1 ) {  
            int d = ((( int ) data[i]) & 0x0ff ) << 16 ;  
       
            buf.append(legalChars[(d >> 18 ) & 63 ]);  
            buf.append(legalChars[(d >> 12 ) & 63 ]);  
            buf.append( "==" );  
        }  
       
        return buf.toString();  
    }  
       
    private static int decode( char c) {  
        if (c >= 'A' && c <= 'Z' )  
            return (( int ) c) - 65 ;  
        else if (c >= 'a' && c <= 'z' )  
            return (( int ) c) - 97 + 26 ;  
        else if (c >= '0' && c <= '9' )  
            return (( int ) c) - 48 + 26 + 26 ;  
        else 
            switch (c) {  
            case '+' :  
                return 62 ;  
            case '/' :  
                return 63 ;  
            case '=' :  
                return 0 ;  
            default :  
                throw new RuntimeException( "unexpected code: " + c);  
            }  
    }  
       
    /** 
     * Decodes the given Base64 encoded String to a new byte array. The byte array holding the decoded data is returned. 
     */ 
       
    public static byte [] decode(String s) {  
       
        ByteArrayOutputStream bos = new ByteArrayOutputStream();  
        try {  
            decode(s, bos);  
        } catch (IOException e) {  
            throw new RuntimeException();  
        }  
        byte [] decodedBytes = bos.toByteArray();  
        try {  
            bos.close();  
            bos = null ;  
        } catch (IOException ex) {  
            System.err.println( "Error while decoding BASE64: " + ex.toString());  
        }  
        return decodedBytes;  
    }  
       
    private static void decode(String s, OutputStream os) throws IOException {  
        int i = 0 ;  
       
        int len = s.length();  
       
        while ( true ) {  
            while (i < len && s.charAt(i) <= ' ' )  
                i++;  
       
            if (i == len)  
                break ;  
       
            int tri = (decode(s.charAt(i)) << 18 ) + (decode(s.charAt(i + 1 )) << 12 ) + (decode(s.charAt(i + 2 )) << 6 ) + (decode(s.charAt(i + 3 )));  
       
            os.write((tri >> 16 ) & 255 );  
            if (s.charAt(i + 2 ) == '=' )  
                break ;  
            os.write((tri >> 8 ) & 255 );  
            if (s.charAt(i + 3 ) == '=' )  
                break ;  
            os.write(tri & 255 );  
       
            i += 4 ;  
        }  
    } 
    public static void main(String[] args) {
		byte[] cardno=new byte[]{'A','B','C','D'};
		String encodeString=encode(cardno);
		String basejava=new BASE64Encoder().encode(cardno);
		byte[] castle=org.bouncycastle.util.encoders.Base64.encode(cardno);
		castle=java.util.Base64.getEncoder().encode(cardno);
		cardno=decode(encodeString);
		System.out.println(cardno);
	}
}

其他可参考:http://blog.csdn.net/huangyunzeng2008/article/details/6563711
http://blog.csdn.net/lonelyroamer/article/details/7638435

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值