zoukankan      html  css  js  c++  java
  • Base64编码Java实现

    一、什么是Base64编码

    Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一。Base64 主要不是加密,它主要的用途是把一些二进制数转成普通字符用于网络传输。 由于一些二进制字符在传输协议中属于控制字符,不能直接传送需要转换一下。Base64编码就是把二进制字节序列转化为ASCII字符序列。一般增加1/3长度,而且也是不可读的。 使用的字符包括大小写字母各26个,加上10个数字,和加号“+”,斜杠“/”,一共64个字符,等号“=”用来作为后缀用途。

    二、Base64原理

    [源数据]——>[获得源数据的二进制流]——>[每3个8位二进制转换为4个6位二进制]——>[每6位二进制转换为十进制]——>[对照表转换为Base64数据]

    关键点:3个8位二进制转换4个6位二进制的方法 将输入的二进制数据流以每次读取6个bit的方式读取,不足6位的后补0,将每3个8位二进制转换为4个6位二进制,也就是说每3个8位字节将编码为4个6位字节(3×8 → 4×6);不满4个字节的以“=”填充。其实这4个六位字节仍然是8位,只不过高两位被设置为0。当一个字节只有6位有效时,它的取值空间为0 到 2的6次方减1 即63,也就是说被转换的Base64编码的每一个编码的取值空间为(0-63)。事实上,0-63之间的ASCII码有许多不可见字符,所以应该再做一个映射,映射表(码表)为:

    码字个数ASCII码对应的6bit值
    0 - 9 10个 48 - 57 52 - 61
    A - Z 26个 65 - 90 0 - 25
    a - z 26个 96 - 122 26 - 51
    + 1个 43 62
    / 1个 47 63

    三、Base64应用

    1.mail

    由于rfc821有以下两条限制:

    1)邮件的内容必须全部为7-比特的美国ascii码。

    2)每一行的长度不能超过1000的字符 当邮件中有其他的非ASCII字符或二进制数据时,就需要做转换。这个就叫做Content-Transfer-Encoding,Base64就是其中的一种方法。在firefox你可以设置自己发送邮件的内容传输编码方式。在收到的邮件里,你可以查看邮件原文,看看原文的编码。

    2.URL

    有些应用需要把二进制数据放到URL里,URL只能是特定的一些ASCII字符。这时候,也需要用到BASE64编码。当然这也只是对二进制数据本身的编码,编码后的数据里面可能包含+/,真正放到URL里面时候,还需要URL-Encoding,变成%XX模式。

    3.HTML中内嵌图片

    就是说这种状况下,图片不是以链接地址的方式嵌到HTML中去的,图片本身已被BASE64成字符串放到HTML页面文本中去了,成为HTML文本的一部分。当HTML页面拉取完成之后,图片数据也就下来了,不再需要再去拉取图片.如下格式:

    <img src='data:image/png;base64,base64code'>

    这种标签图片的显示需要浏览器的支持,先Base64解码,再去显示不同格式的图片。 使用data: URI直接在网页中嵌入,data: URI定义于IETF标准的RFC 2397。 data: URI的基本使用格式如下:

    data:[<MIME-type>][;base64|charset=some_charset],<data>

    mime-type是嵌入数据的mime类型,比如png图片就是image/png。如果后面跟base64,说明后面的data是采用base64方式进行编码的。 获得图片的base64编码,base64编码工具不少,对于前端制作,下面这个本地图片base64编码获取页面是值得推荐的: *Encode Data URL By PuterJam *

    4.简单加密

    迅雷等下载工具,就有他们自己特有的下载链接,如thunder://其实就是把一个HTTP URL资源地址加上了某些东西后再进行BASE64编码,然后加上thunder://头。 垃圾讯息传播者用Base64来避过反垃圾邮件工具,因为那些工具通常都不会翻译Base64的讯息。

    5.百度地图地址转化

    百度地图api的地址转化(例如gps坐标->百度地图坐标)结果,使用了base64加密。

    四、Java编码实现

      1 /**
      2  * 
      3  * @ClassName: SecurityBase64
      4  * @Description: 用于编码请求参数
      5  * @author BuilderQiu
      6  * @date 2013-9-23 上午10:52:1
      7  */
      8 public class SecurityBase64 {
      9     //对照表
     10     private static String base64hash = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/";
     11     //"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/";
     12     private SecurityBase64(){}
     13     private static class TEMP{
     14         public static final SecurityBase64 instance = new SecurityBase64();
     15     }
     16     public static Security getInstance(){
     17         return TEMP.instance;
     18     }
     19     private void checkSecurity(){
     20         if("".equals(base64hash)||base64hash==null||base64hash.length()!=64){
     21             throw new RuntimeException(Security.class+"was initialize failed!");
     22         }
     23     }
     24     /**
     25      * 
     26      * @Title: encode
     27      * @Description: 编码
     28      * @param @param src
     29      * @param @return
     30      * @return String
     31      * @throws
     32      */
     33     public String encode(String src){
     34         checkSecurity();
     35         StringBuilder result = new StringBuilder();
     36         byte[] bytes = src.getBytes();
     37         int length = bytes.length;
     38         int mod = 0;
     39         byte prev = 0;
     40         for(int i=0;i<length;i++){
     41             mod = i%3;
     42             if(mod==0){
     43                 result.append(base64hash.charAt((bytes[i] >> 2) & 0x3F));
     44             }else if(mod==1){
     45                 result.append(base64hash.charAt((prev << 4 | bytes[i] >> 4  &0x0F )& 0x3F));
     46             }else{
     47                 result.append(base64hash.charAt((bytes[i] >> 6 & 0x03 | prev << 2) & 0x3F));
     48                 result.append(base64hash.charAt(bytes[i] & 0x3F));
     49             }
     50             prev = bytes[i];
     51         }
     52         if(mod==0){
     53             result.append(base64hash.charAt(prev << 4 & 0x3C));
     54             result.append("==");
     55         }else if(mod==1){
     56             result.append(base64hash.charAt(prev << 2 & 0x3F));
     57             result.append("=");
     58         }
     59         return result.toString();
     60     }
     61     /**
     62      * 
     63      * @Title: decode
     64      * @Description: 解码
     65      * @param @param src
     66      * @param @return
     67      * @return String
     68      * @throws
     69      */
     70     public String decode(String src){
     71         if(StringUtil.isBlank(src)){
     72             return "";
     73         }
     74         checkSecurity();
     75         byte temp = 0;
     76         String result = "";
     77         for(int i=0;i<src.length();i++){
     78             temp = (byte) base64hash.indexOf(src.charAt(i));
     79             if(temp==-1){
     80                 result+="000000";
     81             }else{
     82                 String t = Integer.toBinaryString(temp);
     83                 if(t.length()==7){
     84                     t = t.substring(1);
     85                 }else if(t.length()==8){
     86                     t = t.substring(2);
     87                 }
     88                 while(t.length()<6){
     89                     t = "0"+t;
     90                 }
     91                 result+=t;
     92             }
     93         }
     94         while(result.endsWith("00000000")){
     95             result = result.substring(0,result.length()-8);
     96         }
     97         byte[] bytes = new byte[result.length()/8];
     98         for(int i=0;i<bytes.length;i++){
     99             bytes[i]= Integer.valueOf(result.substring(i*8,(i+1)*8),2).byteValue();
    100         }
    101         return new String(bytes);
    102     }
    103     public void setBase64hash(String base64hash) {
    104         Security.base64hash = base64hash;
    105     }
    106     /**
    107      * 
    108      * @Title: randomTable
    109      * @Description: 生成随机对照表
    110      * @param @return
    111      * @return String
    112      * @throws
    113      */
    114     public static String randomTable(){
    115         String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-/";
    116         List<Character> list = new ArrayList<Character>();
    117         for(int i=0;i<base.length();i++){
    118             list.add(base.charAt(i));
    119         }
    120         Collections.shuffle(list);
    121         base = "";
    122         for(Character ch:list){
    123             base += ch;
    124         }
    125         return base;
    126     }
    127 }
  • 相关阅读:
    sqlserver还原差异备份
    Hibernate关联关系配置(一对多、一对一和多对多)
    防止用户重复提交表单数据,session方式,js方式
    poi中文api文档
    使用poi调整字体格式、添加单元格注释、自动调整列宽
    jQuery中的几个案例:隔行变色、复选框全选和全不选
    使用poi统计工作职责
    文件上传框的美化+预览+ajax
    web.xml配置文件详解
    findBug 错误修改指南
  • 原文地址:https://www.cnblogs.com/libaoting/p/4108696.html
Copyright © 2011-2022 走看看