1. 程式人生 > >Java實現Base64互相編解碼轉換圖片與字串

Java實現Base64互相編解碼轉換圖片與字串

Base64基本演算法原理

字串例項(對s13進行Base64編解碼)
測試:s13
編碼:czEz
解碼:s13

如何編碼s13為czEz的過程分析:

Base64要求把每三個8Bit的位元組轉換為四個6Bit的位元組(3*8 = 4*6 = 24),然後把6Bit再添兩位高位0,組成四個8Bit的位元組,也就是說,轉換後的字串理論上將要比原來的長1/3。
s13二進位制之間的3*8到4*6的過程
115 49 51
01110011 00110001 00110011(asc轉到二進位制)
011100 110011 000100 110011(分為4組)
00011100 00110011 00000100 00110011(補全8位一組)
28 51 4 51(得到編碼後的asc)
czEz(對應的字串)
———百度百科

這裡介紹三種方法:
1 使用commons-codec.jar包
下載地址http://commons.apache.org/proper/commons-codec/download_codec.cgi
Commons專案中用來處理常用的編碼方法的工具類包,例如DES、SHA1、MD5、Base64,URL,Soundx等
不僅是編碼,也可用於解碼。
2 使用sun.misc.BASE64Encoder
JDK中包含了BASE64Encoder,可以直接使用,但是因為它不屬於JDK的標準庫範疇,所以eclipse無法直接找到,需要進行相關的配置;
3 直接編寫base64的轉換邏輯
使用base64進行對位元組的轉換

commons-codec.jar進行base64轉換

// 需要下載應用commons-codec.jar包
package commonscodec.demo.base64;

import java.io.UnsupportedEncodingException;
import org.apache.commons.codec.binary.Base64;

public class Main {
    public static void main(String[] args) {

        String str = "s13";
        Base64 base64 = new
Base64(); try { str = base64.encodeToString(str.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } System.out.println("Base64 編碼後:" + str); } }

sun.misc.BASE64Encoder進行base64轉換

// 如果找不到sun.misc.BASE64Decoder包,需要進行相關的配置
package sunmisc.demo.base64;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
///
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class Main {
    public static void main(String[] args) {
        String strImg = GetImageStr();
        System.out.println(strImg);
        GenerateImage(strImg);
    }

    // 圖片轉化成base64字串
    public static String GetImageStr() {
        // 將圖片檔案轉化為位元組陣列字串,並對其進行Base64編碼處理
        String imgFile = "d://test.png";
        InputStream in = null;
        byte[] data = null;
        // 讀取圖片位元組陣列
        try {
            in = new FileInputStream(imgFile);
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 對位元組陣列Base64編碼
        BASE64Encoder encoder = new BASE64Encoder();
        // 返回Base64編碼過的位元組陣列字串
        return encoder.encode(data);
    }

    // base64字串轉化成圖片
    public static boolean GenerateImage(String imgStr) {
        // 對位元組陣列字串進行Base64解碼並生成圖片
        if (imgStr == null)
            return false;
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            // Base64解碼
            byte[] b = decoder.decodeBuffer(imgStr);
            for (int i = 0; i < b.length; ++i) {
                if (b[i] < 0) {// 調整異常資料
                    b[i] += 256;
                }
            }
            // 生成新的圖片
            String imgFilePath = "d://222.png";
            OutputStream out = new FileOutputStream(imgFilePath);
            out.write(b);
            out.flush();
            out.close();
            return true;
        } catch (Exception e) {
            return false;
        }
    }
}

如果找不到sun.misc.BASE64Decoder包,需要進行相關的配置如下
右鍵專案-》屬性-》Java bulid path-》jre System Library-》access rules-》resolution選擇accessible填上** ,點選確定完成配置
這裡寫圖片描述

直接編寫邏輯進行base64轉換

//來自http://blog.csdn.net/lastsweetop/article/details/5314640
package com.test.base64;

public class Main {
    /**
     * 將原始資料編碼為base64編碼
     */
    static public char[] encode(byte[] data) {
        char[] out = new char[((data.length + 2) / 3) * 4];
        for (int i = 0, index = 0; i < data.length; i += 3, index += 4) {
            boolean quad = false;
            boolean trip = false;
            int val = (0xFF & (int) data[i]);
            val <<= 8;
            if ((i + 1) < data.length) {
                val |= (0xFF & (int) data[i + 1]);
                trip = true;
            }
            val <<= 8;
            if ((i + 2) < data.length) {
                val |= (0xFF & (int) data[i + 2]);
                quad = true;
            }
            out[index + 3] = alphabet[(quad ? (val & 0x3F) : 64)];
            val >>= 6;
            out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
            val >>= 6;
            out[index + 1] = alphabet[val & 0x3F];
            val >>= 6;
            out[index + 0] = alphabet[val & 0x3F];
        }
        return out;
    }

    /**
     * 將base64編碼的資料解碼成原始資料
     */
    static public byte[] decode(char[] data) {
        int len = ((data.length + 3) / 4) * 3;
        if (data.length > 0 && data[data.length - 1] == '=')
            --len;
        if (data.length > 1 && data[data.length - 2] == '=')
            --len;
        byte[] out = new byte[len];
        int shift = 0;
        int accum = 0;
        int index = 0;
        for (int ix = 0; ix < data.length; ix++) {
            int value = codes[data[ix] & 0xFF];
            if (value >= 0) {
                accum <<= 6;
                shift += 6;
                accum |= value;
                if (shift >= 8) {
                    shift -= 8;
                    out[index++] = (byte) ((accum >> shift) & 0xff);
                }
            }
        }
        if (index != out.length)
            throw new Error("miscalculated data length!");
        return out;
    }

    static private char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
            .toCharArray();
    static private byte[] codes = new byte[256];
    static {
        for (int i = 0; i < 256; i++)
            codes[i] = -1;
        for (int i = 'A'; i <= 'Z'; i++)
            codes[i] = (byte) (i - 'A');
        for (int i = 'a'; i <= 'z'; i++)
            codes[i] = (byte) (26 + i - 'a');
        for (int i = '0'; i <= '9'; i++)
            codes[i] = (byte) (52 + i - '0');
        codes['+'] = 62;
        codes['/'] = 63;
    }

    public static void main(String[] args) throws Exception {
        // 加密成base64
        String strSrc = "s13";
        String strOut = new String(Main.encode(strSrc.getBytes("GB18030")));
        System.out.println("測試:s13");
        System.out.println("編碼:" + strOut);
        String strOut2 = new String(Main.decode(strOut.toCharArray()),
                "GB18030");
        System.out.println("解碼:" + strOut2);
    }
}
測試:s13
編碼:czEz
解碼:s13