`

Base64扩展,自定义字串和顺序

 
阅读更多

 

Base64很标准,sun 的 jdk 包含了实现,JS 也有许多可选实现。已知 sun 的 Base64 性能不行,远不及自己写的代码,这并不重要,无须深究。比较关注的是通常 JS 到 JAVA 间通常是私有的 Base64 编码和解码,如果采用公共的方式编码与解码,不能实现简单的加密。但可以通过适当的修改 Base64 来实现简单加密与解密。尽管不及专门的对称加密和非对称加密的安全性,但性能远胜于专门的加密解密过程,且可以实现可见字符的传输。适用于安全要求不高,对密文要求可见,且密文长度受限的场景。

 

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * @author michael
 * 
 */
public class Base64x {
	private static final String DEFAULT_ENCODING_TABLES = "ABCDEFGHIJKLMNOPQRSTUVWXYZ+abcdefghijk0123456789/lmnopqrstuvwxyz";
	private String encodingTables = "";
	public Base64x(int offset) {
		int move = offset % DEFAULT_ENCODING_TABLES.length();
		this.encodingTables = DEFAULT_ENCODING_TABLES.substring(move) + DEFAULT_ENCODING_TABLES.substring(0, move);
	}

	/**
	 * encode
	 * 
	 * coverts a byte array to a string populated with base64 digits. It steps
	 * through the byte array calling a helper methode for each block of three
	 * input bytes
	 * 
	 * @param raw
	 *            The byte array to encode
	 * @return A string in base64 encoding
	 */
	public String encode(byte[] raw) {
		StringBuffer encoded = new StringBuffer();
		for (int i = 0; i < raw.length; i += 3) {
			encoded.append(encodeBlock(raw, i));
		}
		return encoded.toString();
	}

	/**
	 * encodeBlock
	 * 
	 * creates 4 base64 digits from three bytes of input data. we use an
	 * integer, block, to hold the 24 bits of input data.
	 * 
	 * @return An array of 4 characters
	 */
	protected char[] encodeBlock(byte[] raw, int offset) {
		int block = 0;
		// how much space left in input byte array
		int slack = raw.length - offset - 1;
		// if there are fewer than 3 bytes in this block, calculate end
		int end = (slack >= 2) ? 2 : slack;
		// convert signed quantities into unsigned
		for (int i = 0; i <= end; i++) {
			byte b = raw[offset + i];
			int neuter = (b < 0) ? b + 256 : b;
			block += neuter << (8 * (2 - i));
		}
		// extract the base64 digets, which are six bit quantities.
		char[] base64 = new char[4];
		for (int i = 0; i < 4; i++) {
			int sixbit = (block >>> (6 * (3 - i))) & 0x3f;
			base64[i] = getChar(sixbit);
		}
		// pad return block if needed
		if (slack < 1)
			base64[2] = '=';
		if (slack < 2)
			base64[3] = '=';
		// always returns an array of 4 characters
		return base64;
	}

	/**
	 * decode
	 * 
	 * convert a base64 string into an array of bytes.
	 * 
	 * @param base64
	 *            A String of base64 digits to decode.
	 * @return A byte array containing the decoded value of the base64 input
	 *         string
	 */
	public byte[] decode(String base64) {
		// how many padding digits?
		int pad = 0;
		for (int i = base64.length() - 1; base64.charAt(i) == '='; i--)
			pad++;
		// we know know the lenght of the target byte array.
		int length = base64.length() * 6 / 8 - pad;
		byte[] raw = new byte[length];
		int rawIndex = 0;
		// loop through the base64 value. A correctly formed
		// base64 string always has a multiple of 4 characters.
		for (int i = 0; i < base64.length(); i += 4) {
			int block = (getValue(base64.charAt(i)) << 18) + (getValue(base64.charAt(i + 1)) << 12) + (getValue(base64.charAt(i + 2)) << 6)
					+ (getValue(base64.charAt(i + 3)));
			// based on the block, the byte array is filled with the
			// appropriate 8 bit values
			for (int j = 0; j < 3 && rawIndex + j < raw.length; j++)
				raw[rawIndex + j] = (byte) ((block >> (8 * (2 - j))) & 0xff);
			rawIndex += 3;
		}
		return raw;
	}

	/**
	 * getChar
	 * 
	 * encapsulates the translation from six bit quantity to base64 digit
	 */
	protected char getChar(int sixBit) {
		return encodingTables.charAt(sixBit);
	}

	/**
	 * getValue
	 * 
	 * translates from base64 digits to their 6 bit value
	 */
	protected int getValue(char c) {
		if (c == '=')
			return 0;
		return encodingTables.indexOf(c);
	}

	public static void main(String[] args) {
		String data = "试一试中文也行。";
		Base64x b = new Base64x(0);
		String result = b.encode(data.getBytes());
		System.out.println(data);
		System.out.println(new String(result));
		System.out.println(new String(b.decode(result)));
	}
	
}
 
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics