說說base64位編碼。

   雖然網絡上已經有許多的關於base64編碼的介紹,但是自己還是想總結一點,爲了以後防止自己忘記。先給大家看一串代碼,出去就不明說了,這是一串利用base64對字符串進行編碼的java代碼。

public class BASE64Encoder
{
private static final char LAST2BYTE = (char) Integer.parseInt("00000011", 2);
private static final char LAST4BYTE = (char) Integer.parseInt("00001111", 2);
private static final char LAST6BYTE = (char) Integer.parseInt("00111111", 2);
private static final char LEAD6BYTE = (char) Integer.parseInt("11111100", 2);
private static final char LEAD4BYTE = (char) Integer.parseInt("11110000", 2);
private static final char LEAD2BYTE = (char) Integer.parseInt("11000000", 2);
private static final char[] ENCODE_TABLE = new char[] { 'A', 'B', 'C', 'D',   'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q','R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd','e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q','r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3','4', '5', '6', '7', '8', '9', '+', '/' };
private static final String DEFAULT_ENCODING = "UTF-8";  //指定編碼集
public BASE64Encoder()  
{
}
public static String encode(String data)
throws UnsupportedEncodingException
{
return encode(data.getBytes(DEFAULT_ENCODING));
}
public static String encode(byte[] from)
{
StringBuffer to = new StringBuffer((int) (from.length * 1.34) + 3);
int num = 0;
char currentByte = 0;
for (int i = 0; i < from.length; i++)
{
num = num % 8;
while (num < 8)
{
switch (num)
{
case 0:
currentByte = (char) (from[i] & LEAD6BYTE);
currentByte = (char) (currentByte >>> 2);
break;
case 2:
currentByte = (char) (from[i] & LAST6BYTE);
break;
case 4:
currentByte = (char) (from[i] & LAST4BYTE);
currentByte = (char) (currentByte << 2);
if ((i + 1) < from.length)
{
currentByte |= (from[i + 1] & LEAD2BYTE) >>> 6;
}
break;
case 6:
currentByte = (char) (from[i] & LAST2BYTE);
currentByte = (char) (currentByte << 4);
if ((i + 1) < from.length)
{
currentByte |= (from[i + 1] & LEAD4BYTE) >>> 4;
}
break;
}
to.append(ENCODE_TABLE[currentByte]);
num += 6;
}
}
if (to.length() % 4 != 0)
{
for (int i = 4 - to.length() % 4; i > 0; i--)
{
to.append("=");
}
}
return to.toString();
}

}

  base64是一種基於64個可打印字符來表示二進制數據的表示方法,由於2的6次方等於64,所以每6個比特爲一個單元,對應某個可打印字符。然後在6位前面補2個0形成一個8位的字節形式。例如我現在有一個24位的字節。它是3*8=24的形式,然後我們要把它分成4*6=24的形式。

eg: 11010101 11000101 00110011 (3*8=24)

     00110101 00011100 00010100 00110011(4*6=24)

就是按順序先拿出左邊的6個位:110101 然後在最前面補2個0,形成00110101 這樣就是第一個字節了。

然後接着取剩下的6位01 1100 ,前面補2個0變成00011100。

最後按順序再去6位:010100 ,前面補2個0變成00010100.

同理最後剩下的6位:110011,前面補2個0變成00110011.

接下來我們來進行base64編碼。先將所有的二進制轉換成10進制,在從我們的encode_table裏面找對應的數。其實encode——table裏面的數就是字母A-Z、a-z、數字0-9,這樣共有62個字符,此外的兩個可打印符號在不同的系統中而不同,一般爲+和/。注意47 v還有一個說法 47 pad = 

只是需要找到他們對應的序號。附上encdode_table表:


舉個例子如何找:

例如有一個2進制數:00110101 編碼後變成什麼呢?(假裝這個數是已經從8位變成6位在加了0的)

先對它進行二進制轉十進制,應該會轉吧。2^5+2^4+2^2+2^0=53,然後找到對應表中的數字就是53對應是1.base64編碼得到的結果爲1。

接下來都介紹了,就來整體的練習一個。

字符串“張3"進行base64編碼得到是什麼呢?

這裏涉及到中文轉二進制的操作。提供一個方法將字符串轉爲二進制的,我提供的是Java代碼

String str = "張3";
   byte[] b = str.getBytes();
   for(int i=0;i<b.length;i++){
       System.out.println(Integer.toBinaryString(b[i]&0xff));
 }

然後得到11010101 11000101 00110011 (3*8)

    00110101 00011100 00010100 00110011(4*6)

都轉換爲十進制爲 53  28   20  51

對照表所以轉換後得到的base64編碼爲:1cUz   好啦,就這樣轉完了。

不過還得說一個問題。要是你的數湊不成6的倍數呢。

eg:11010101 11000101(2*8=16)

00110101 00011100 00010100(按照我們這樣話分,前面補2個0,最後一個數也會只有6個,這樣就在最後補0,缺幾個補幾個0,湊足8位就行)化成十進制:53  28    20 pad (只有末尾補了0的記得就要寫上pad)

這樣base64編碼就是:1cU=  (因爲pad對應的是等於)。

--後續:後來我在前端裏也遇見了需要用簽名的地方,是用的名爲cryptojs 的庫,裏面提供了多種javascript編寫的算法,很方便。

說一說後續使用的用ts編寫的一段用於計算簽名的算法:(上面提到過,之前使用的是關於crypto的庫,直接用庫裏面的方法計算就行);

 getData(data, app_secret) {
        let myData = [];
        for (let x in data) {
            let temp = `${x}=${data[x]}`;
            myData.push(temp);
        }
        let result = myData.sort().join('&');
        let b = new window['Base64']();
        let sign = window['CryptoJS'].MD5(window['CryptoJS'].HmacSHA1(b.encode(result), app_secret)).toString();
        return sign;
    }

歡迎指教,如果有不對的,記得告訴我。

Thanks



 

    



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章