读书人

Base64扩张自定义字串和顺序

发布时间: 2012-12-16 12:02:32 作者: rapoo

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 arrayint slack = raw.length - offset - 1;// if there are fewer than 3 bytes in this block, calculate endint end = (slack >= 2) ? 2 : slack;// convert signed quantities into unsignedfor (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 neededif (slack < 1)base64[2] = '=';if (slack < 2)base64[3] = '=';// always returns an array of 4 charactersreturn 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 valuesfor (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)));}}
?

读书人网 >软件开发

热点推荐