天天看點

【編碼】Base64編碼

簡述

為什麼叫Base64?個人了解是,基礎的64個字元。

而它的作用?用基礎的(可了解為可安全傳輸的)64個字元,來表示難以表示的二進制或對程式造成幹擾的字元。

Base64的編碼過程

【編碼】Base64編碼

自行編碼分析Base64的編碼方式

Base64的編碼範圍

import org.junit.Test;

public class Base64Map {
	
	public static char[] chars = new char[64];
	
	static {
		for (int i = 0; i < 26; i++) {
			chars[i] = (char)((int)'A' + i);
		}
		for (int i = 26; i < 52; i++) {
			chars[i] = (char)((int)'a' + i - 26);
		}
		for (int i = 52; i < 62; i++) {
			chars[i] = (char)((int)'0' + i - 52);
		}
		chars[62] = '+';
		chars[63] = '/';
	}
	
	/**
	 * 擷取對應的Base64字元
	 * @param index 下标
	 * @return 對應的Base64字元
	 */
	public static char getBase64(int index) {
		return chars[index];
	}
	
	@Test
	public void printAll() {
		System.out.println(chars);
	}

}
           

即:

ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
           

簡單的二進制工具

import org.junit.Test;

public class BinaryUtils {
	
	/**
	 * 将多個位元組轉換為能列印的位
	 * @param b 多個位元組
	 * @return 能列印的位
	 */
	public static String bytes2Bit(byte[] bytes) {
		StringBuffer sb = new StringBuffer();
		for (byte b : bytes) {
			sb.append(BinaryUtils.byte2Bit(b));
		}
		return sb.toString();
	}

	/**
	 * 将位元組轉換為能列印的位
	 * @param b 位元組
	 * @return 能列印的位
	 */
	public static String byte2Bit(byte b) {
		/* 備注:也可用JDK方法實作:Integer.toBinaryString() */
		
		StringBuffer sb = new StringBuffer();
		for (int i = 7; i >= 0; i--) { // 右移i位
			sb.append((byte) ((b >> i) & 1));
		}
		return sb.toString();
	}
	
	/**
	 * 二進制轉換為十進制
	 * @param binary 二進制
	 * @return 十進制
	 */
	public static Integer binary2Decimal(String binary) {
		if (binary == null || binary.trim().length() == 0) {
			return null;
		}
		
		binary = binary.trim();
		char[] chars = binary.toCharArray();
		
		int sum = 0;
		for (int i = chars.length - 1; i >= 0; i--) {
			if (chars[i] == '0') {
				continue;
			}
			sum = sum + (int)Math.pow(2, chars.length - 1 - i);
		}
		return sum;
	}
	
	@Test
	public void bytes2BitTest() {
		System.out.println(BinaryUtils.bytes2Bit("hello".getBytes()));
	}
	
	@Test
	public void byte2BitTest() {
		System.out.println(BinaryUtils.byte2Bit("h".getBytes()[0]));
		System.out.println(Integer.toBinaryString("h".getBytes()[0]));
	}
	
	@Test
	public void binary2DecimalTest() {
		System.out.println(BinaryUtils.binary2Decimal("011010"));
	}

}

           

簡單的編碼過程

public class Base64Analyzer {

	public static void main(String[] args) {
		/* TODO
		 * 此為練習,部分邏輯未實作:
		 * 1、無考慮補位到6、8的公倍數情況;
		 * 2、無考慮6位全部為補位,編碼為=的情況
		 */
		
		/* 轉換為二進制 */
		String bitStr = BinaryUtils.bytes2Bit("hello".getBytes());
		System.out.println(bitStr);
		
		int bitSize = 6;
		String sixBitStr = null;
		Integer index = null;
		char base64Char;
		StringBuffer base64SB = new StringBuffer();
		for (int i = 0; i < bitStr.length(); i += 6) {
			/* 二進制按6位分組 */
			sixBitStr = bitStr.substring(i, i + 6 > bitStr.length() ? bitStr.length() : i + 6);
			if (sixBitStr.length() != 6) {
				sixBitStr = sixBitStr + String.format("%0" + (bitSize - sixBitStr.length()) + "d", 0); // 不足位後補0
			}
			
			// 将每6位的字元轉換為十進制
			index = BinaryUtils.binary2Decimal(sixBitStr);
			
			// 根據下标擷取對應的Base64字元
			base64Char = Base64Map.getBase64(index);
			System.out.println(sixBitStr + " -> " + base64Char);
			base64SB.append(base64Char);
		}
		
		System.out.println(base64SB.toString());
	}

}
           

日志:

0110100001100101011011000110110001101111
011010 -> a
000110 -> G
010101 -> V
101100 -> s
011011 -> b
000110 -> G
111100 -> 8
aGVsbG8
           

JDK轉換Base64的方式

下例是JDK1.8的方法:

import java.util.Base64;

import org.junit.Test;

public class Base64Util {
	
	public static String encode(byte[] bytes) {
		return Base64.getEncoder().encodeToString(bytes);
	}
	
	public static byte[] decode(String s) {
		return Base64.getDecoder().decode(s);
	}
	
	@Test
	public void encodeTest() {
		System.out.println(Base64Util.encode("hello".getBytes()));
	}
	
	@Test
	public void decodeTest() {
		System.out.println(new String(Base64Util.decode("aGVsbG8=")));
	}

}
           

參考文章

讓你完全了解base64是怎麼回事

作者:Nick Huang 部落格:http://www.cnblogs.com/nick-huang/

本部落格為學習、筆記之用,以筆記形式記錄學習的知識與感悟。學習過程中可能參考各種資料,如覺文中表述過分引用,請務必告知,以便迅速處理。如有錯漏,不吝賜教。

如果本文對您有用,

點贊

評論

哦;如果您喜歡我的文章,請點選

關注我

哦~