Java安全之Base64算法

Base64算法常作为密钥,密文和证书的一种通用存储编码格式

主要用来增加易读性,隐蔽信息并不能起到加密的作用。


实现原理

将给定的字符串转换为二进制码

每6位为一个Base64字节,4个Base64字节为一组(不足6位时低位补0)

将每个Base64字节高位补2个0转为10进制码

对应码表转成对应的字符

=号进行补位 余数=原文字节数 mod 3

余0不补 余1补2个= 余2补1个=

根据RFC2045 每76位追加一个回车换行符 /r/n


GB2312 GBK用2个字节表示一位汉字

UTF-8用3个字节表示一位汉字


BC中使用Base64Coder类

CC中使用Base64类


值得一提的是Java API中并没有相关实现

但在 sun.misc包中有2个类 BASE64Encoder和Base64Decoder这两个实现

正式的项目中最好不要使用

因为以sun和com.sun包开头的包的类都是未被文档化的 编译器有如是警告“Sun的专业API,可能会在未来版本中删除”


UrlBase64

将+与/ 分别替换成-与_ 填充符用 .或者~

BC CC都有相应实现Url Base64 不同的是BC使用.作为填充符而CC放弃了填充符


Base64广泛应用于电子邮件传输(电子邮件只允许使用ASCII码),以及密钥和证书文件的文本方式保存。


最后是Java实现

public class MyBase64 {
	 private static String base64Code= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 
	 	
	 public static void main(String[] args) throws UnsupportedEncodingException  {
		System.out.println(encode("密码abc".getBytes()));
		System.out.println(Base64.encode("密码abc".getBytes()));
	}
	/**
	 * 只适用于英文
	 * 
	 * @param str 要编码的字符串
	 * @return 该字符串的base64编码
	 */
	public static String encode(String str){
        //有效值检查  
        if(str == null || str.length() == 0) {  
            return null;  
        }  
        //将明文的ASCII码转为二进制位字串  
        char[] chars= str.toCharArray();  
        StringBuilder sb= new StringBuilder();  
        String s= null;  
        for(int i= 0; i< chars.length; i++) {  
            s= Integer.toBinaryString((chars[i]&0xff)+0x100).substring(1);
            while(s.length()< 8) {
                s= "0"+ s;  
            } 
            if(s.length()>8){
            	while(s.length()< 16) {
                    s= "0"+ s;  
                } 
            }
            sb.append(s);  
        }
        
        while(sb.length()%6!=0){
		sb.append("0");  
        }
        String b64=sb.toString();
        char[] ch=new char[b64.length()/6];
        for(int i=0;i<ch.length;i++){
        	ch[i]=base64Code.charAt(Integer.parseInt(b64.substring(0+i*6, 6+i*6), 2));
        }
        
        sb=new StringBuilder(String.valueOf(ch));
        if(str.length()%3==1)
        	sb.append("==");
        if(str.length()%3==2)
        	sb.append("=");
        return sb.toString();        
	}
	
	/**
	 * 与官方实现结果相同
	 * 
	 * @param bytes 传入的字节数组
	 * @return 该字节数组的base64编码
	 */
	public static String encode(byte[] bytes){
		StringBuilder sb=new StringBuilder();
		for(byte b:bytes){
			String s=Integer.toBinaryString((b&0xff)+0x100).substring(1);
			sb.append(s);
		}
		
		
		while(sb.length()%6 !=0){
			sb.append("0");
		}
		
		String byteString=sb.toString();
		char[] base64=new char[byteString.length()/6];
		for(int i=0;i<base64.length;i++){
			base64[i]=base64Code.charAt(Integer.parseInt(byteString.substring(0+i*6,6+i*6),2));
		}
		
		sb=new StringBuilder(String.valueOf(base64));
		if(bytes.length%3==1)
			sb.append("==");
		if(bytes.length%3==2)
			sb.append("=");
		
		return sb.toString();

	}
	
}

其中第一种方法是网上流传的并不支持中文(有兴趣的可以想下第一种为什么不行,对理解编码底层字节帮助很大)

第二种是我后来自己实现中英文均可

decode与encode类似就没有写



如果觉得有帮助,点下顶哦





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值