Base64自定義編碼表及破解

什麼是Base64

Base64是網絡上最多見的用於傳輸8Bit字節代碼的編碼方式之一,Base64並非安全領域的加密算法,其實Base64只能算是一個編碼算法,對數據內容進行編碼來適合傳輸。標準Base64編碼解碼無需額外信息即徹底可逆,即便你本身自定義字符集設計一種類Base64的編碼方式用於數據加密,在多數場景下也較容易破解。Base64編碼本質上是一種將二進制數據轉成文本數據的方案。對於非二進制數據,是先將其轉換成二進制形式,而後每連續6比特(2的6次方=64)計算其十進制值,根據該值在A--Z,a--z,0--9,+,/ 這64個字符中找到對應的字符,最終獲得一個文本字符串。java

Base64 編碼要求把 3 個 8 位字節(3x8=24)轉化爲 4 個 6 位的字節(4x6=24),以後在 6 位的前面補兩個 0 ,造成 8 位一個字節的形式。 若是剩下的字符不足 3 個字節,則用 0 填充,輸出字符使用 ‘=’,所以編碼後輸出的文本末尾可能會出現 1 或 2 個 ‘=’。git

java實現

public abstract class Base64 {
	private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
			.toCharArray();

	public static String encode(byte[] data) {
		int start = 0;
		int len = data.length;
		StringBuilder buf = new StringBuilder(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();
	}

}

複製代碼

自定義 Base64 編碼表及破解

標準的base64編碼表是A--Z,a--z,0--9,+,/,可是咱們徹底能夠替換這64個字符或者打亂順序,這樣只有咱們知道編碼表才能解碼。經過拼接0~63的6位2進制字符串,而後分割轉換成長度爲48的byte數組,即可以獲得編碼表。詳細步驟以下:算法

  • 計算出0-63這64個數字的6位2進制數,轉換成字符串拼接成一個完整的字符串,長度就是64x6
  • 將字符串每8個(1byte就是8位)一組,分割成48份,48x8
  • 經過Integer.parseInt(binaryString, 2)解析成數字,再強轉成byte
  • 對這個長度爲48的byte數組進行編碼
  • 編碼的結果就是編碼表了
public class test {

    public static void main(String[] args) {

        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < 64; i++) {
            stringBuilder.append(binary2decimal(i, 6));
        }

        byte[] byteDecode = new byte[48];
        System.out.println(stringBuilder.toString());
        for (int i = 0; i < 48; i++) {
            String binaryString = stringBuilder.substring(i * 8, (i + 1) * 8);
            byteDecode[i] = (byte) Integer.parseInt(binaryString, 2);
        }
        System.out.println(Base64.encode(byteDecode));

    }

    //十進制轉換爲指定位數的二進制
    private static String binary2decimal(int decNum, int digit) {
        StringBuilder binStr = new StringBuilder();
        for (int i = digit - 1; i >= 0; i--) {
            binStr.append((decNum >> i) & 1);
        }
        return binStr.toString();
    }

}
複製代碼

打印以下:數組

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567 89+/
複製代碼
相關文章
相關標籤/搜索