zoukankan      html  css  js  c++  java
  • 【编码】Base64编码

    简述

    为什么叫Base64?个人理解是,基础的64个字符。
    而它的作用?用基础的(可理解为可安全传输的)64个字符,来表示难以表示的二进制或对程序造成干扰的字符。

    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是怎么回事

  • 相关阅读:
    segmentation fault(core dumped)
    (LIS LCS 例题)Max Sum Advanced Fruits Super Jumping! Jumping! Jumping!
    几种数学公式(环排列 母函数 唯一分解定理 卡特兰数 默慈金数 贝尔数 那罗延数)
    map set 详解
    算法录 之 二分和三分
    LIS 最长上升子序列 LCS 最长公共子序列 模板
    JAVA 大数据 例题
    Java 实现大数算法
    7 21 第一次团队赛——————写给队友
    离散化+unique()+二分查找
  • 原文地址:https://www.cnblogs.com/nick-huang/p/7039473.html
Copyright © 2011-2022 走看看