My favorites | Sign in
Project Home Downloads Wiki Issues Source
Project Information
Members

更新到v1.2

  • 1)v1.2添加两个类似钩子的加解密函数(encode和decode),方便自定义简单的加解密过程
  • 2)废弃@Deprecated的方法未填加钩子方法
  • 3)优化init方法

更新到v1.1:
  • 1)v1.1开始支持中文等多字节编码字符,对应的编码/解码接口为:
    • 编码:byte encode(byte content)
    • 解码:byte decode(byte content)
  • 上述两个方法与v1.0中的编码思路一致,通过在每三字节前加一字节记录这三字节mod64的情况
  • 不同之处在于记录字节使用两个bit位来记录(v1.0中记录ASCII只用一个bit位),所以相对base64其编码长度仅多一个Bluff code所占的字节
  • 2)v1.0中所有方法都改为 xxxAsciixxx, 以表明只支持ASCII字符
  • 3)v1.1仍然支持BLUFF功能

类似于base64的编码目的,但目前只支持编码基于ASCII的字符。相比base64编码后的字符/节串,其长度更精短,base64编码后的字串会比原串长1/3左右,该方法为1/6。编码/解码速度更快(相比apache commons中的base64实现),对700字节的字符串编/解码100万次(单位:nanoTime):

  • base64:32951698610
  • bama:18900134515

思路:

  1. 类似base64采用码表,通过将源字符对应值转换到码表坐标[0-63]来实现源字符到码表字符的映射。
  2. 与base64不同的是,base64采用截取6位重新构造的方式来将源字符串各字符对应值限制到[0-63],而该方法是通过上图所示:将各字符mod64,并将每6个源字符组合成一组,将它们mod64的信息统一存放在一个字符中(这个字符前6位的每一位用0或1来记录6字符与64的关系),并放置在每组之前。
  3. 通过在编码字符串前放置一个Bluff字符,来进一步扰乱编码字符并实现一定程度编码的随机功能。
  4. 解码的时候,则从Bluff字符后,每7个一组进行解码,先将编码字符通过解码表查出其在编码表中对应的值,然后通过位操作从每组首字符中取得mod64的信息,从而还原出对应源字符在Bluff扰乱后的一个值,再通过Bluff字符对扰乱做逆操作,从而获得源编码
  5. init()方法用于初始化时将编码表和解码表重排序,以避免不同的用户对相同字符串的编码产生相同的编码结果

示例

 	public static void main(String[] args) throws UnsupportedEncodingException {
 		
 		// 如果希望不基于默认编码/解码表的话
 		Obama.init(); 
 		
 		// 如果希望对相同字符串多次编码产生不同的编码结果
 		Obama.BLUFF = true; 
 		
 		// 待编码的字符串
 		String content = "http://aobama.googlecode.com/files/Obama.java"; 
 		
 		for(int i=0; i<3; i++){
 			String encode = Obama.encodeString(content);
 			String decode = Obama.decodeString(encode);
 			System.out.println("编码后:" + encode);
 			System.out.println("解码后:" + decode);
 			System.out.println("---------------------------");
 		}
 		
 	}
 
输出结果
 i=0
 编码后:Qdb4Qn-ZKt30dNbRdtN8kmT8jd833Xzm0zkyaI0e9k2am3tmZtTdOy
 解码后:http://aobama.googlecode.com/files/Obama.java ---------------------------i=1
 编码后:vdLxTupsKGM2JhLRJGhVBqTVrJVMMX6q26BDaP2XAB0aqMGqsGTJKD
 解码后:http://aobama.googlecode.com/files/Obama.java ---------------------------i=2
 编码后:Kdvt8Ij9K4SOfFvRf4FQi7TQ-fQSSXU7OUiWanO1ZiKa7S4794Tf0W
 解码后:http://aobama.googlecode.com/files/Obama.java ---------------------------

部分代码:

  1. 码表
 	
 	/** 编码基表 */
 	private static final char base_encode[] = {
 		// 默认序列
 	    'P', 'e', 'r', 'Q', 'f', 'w', '7', 'g', 'i', 'p', 	/*  0- 9 */
 	    '8', '9', 'B', 'd', 'O', 'v', '6', 'S', 'D', 'M', 	/* 10-19 */
 	    'b', 's', 'R', 'C', 'N', 'c', 'm', '5', 'l', 'z', 	/* 20-29 */
 	    'I', 'X', 'o', 'j', 'H', '2', 'x', 'W', '1', 'J', 	/* 30-39 */
 	    'V', 'h', 'G', '0', 'Y', 'q', 'E', 'T', 'k', '3', 	/* 40-49 */
 	    'a', 'L', 'y', 'n', 't', 'U', 'u', 'Z', '4', 'K', 	/* 50-59 */
 	    'F', 'A', '_', '-'									/* 60-63 */ //95,45, 
 	};
 	
 	/** 解码参照表 */
 	private static int base_decode[] = {
 		// 参照编码表默认序列的值序
 		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  			/*  0- 9 */
 		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  			/*  10- 19 */
 		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  			/*  20- 29 */
 		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  			/*  30- 39 */
 		-1, -1, -1, -1, -1, 63, -1, -1, 43, 38,  			/*  40- 49 */
 		35, 49, 58, 27, 16, 6, 10, 11, -1, -1,  			/*  50- 59 */
 		-1, -1, -1, -1, -1, 61, 12, 23, 18, 46,  			/*  60- 69 */
 		60, 42, 34, 30, 39, 59, 51, 19, 24, 14,  			/*  70- 79 */
 		0, 3, 22, 17, 47, 55, 40, 37, 31, 44,  				/*  80- 89 */
 		57, -1, -1, -1, -1, 62, 0, 50, 20, 25,  			/*  90- 99 */
 		13, 1, 4, 7, 41, 8, 33, 48, 28, 26,  				/*  100- 109 */
 		53, 32, 9, 45, 2, 21, 54, 56, 15, 5,  				/*  110- 119 */
 		36, 52, 29, -1, -1, -1, -1, -1, -1		 			/*  120- 128 */	
 	};
 	
 	/** 	 * 重排序编码基表和对应的解码表
 	 */
 	public static void init(){
 		
 		Random rand = new Random();
 		// 重排序编码基表
 		for (int i=base_encode.length; i>1; i--)
             swap(base_encode, i-1, rand.nextInt(i));
 		
 		// 根据重排序后的编码基表初始化解码表
 		initDecode();
 	}
 	
 	private static void swap(char[] arr, int i, int j) {
         char tmp = arr[i];
         arr[i] = arr[j];
         arr[j] = tmp;
     }
 

  1. 编码方法
 	
 	
 	/** 
 	 * 	编码
 	 * */
 	public static byte[] encodeBytes(byte[] content){
 		
 		if(content==null || content.length==0)
 			return null;
 		
 		int len = content.length;
 		
 		byte[] cArray = new byte[len + (int)Math.ceil(len/6.0d) + 1];
 		
 		if(BLUFF){
 			int s = 0;
 			int r = new Random().nextInt(26);
 			boolean u = ((r ^ len) & 1) == 1;
 			s = u ? 65 : 97;
 			cArray[0] = (byte)(r + s);
 		}else{
 			cArray[0] = DEF_SECRET;
 		}
 		
 		
 		byte c = 0;
 		int n = 0;
 		int mark = 0;
 		int pos = 0;
 		int segs = 0;
 		for(int i=0; i<len; i+=6){
 			mark = 1+i+segs;
 			for(int k=0; (k<6) && (pos<len); k++){
 				c = content[pos];
 				n = c ^ cArray[0]; 
 				n ^= k;
 				cArray[mark] |= ((n>>>6)<<k); 
 				
 				cArray[mark+k+1] = (byte)base_encode[n & MASK_64];
 				pos++;
 			}
 			segs++;
 			cArray[mark] = (byte)base_encode[cArray[mark]];
 		}
 		
 		return cArray;
 		
 	}
 	
 	public static byte[] encodeBytes(String content){
 		
 		if(content==null || content.length()==0)
 			return null;
 		
 		int len = content.length();
 		
 		byte[] cArray = new byte[len + (int)Math.ceil(len/6.0d) + 1];
 		
 		if(BLUFF){
 			int s = 0;
 			int r = new Random().nextInt(26);
 			boolean u = ((r ^ len) & 1) == 1;
 			s = u ? 65 : 97;
 			cArray[0] = (byte)(r + s);
 		}else{
 			cArray[0] = DEF_SECRET;
 		}
 		
 		char c = '0';
 		int n = 0;
 		int mark = 0;
 		int pos = 0;
 		int segs = 0;
 		
 		for(int i=0; i<len; i+=6){
 			mark = 1+i+segs;
 			for(int k=0; (k<6) && (pos<len); k++){
 				c = content.charAt(pos);
 				n = c ^ cArray[0]; 
 				n ^= k;
 				cArray[mark] |= ((n>>>6)<<k); 
 				
 				cArray[mark+k+1] = (byte)base_encode[n & MASK_64];
 				pos++;
 			}
 			segs++;
 			cArray[mark] = (byte)base_encode[cArray[mark]];
 		}
 		
 		return cArray;
 		
 	}
 	
 	public static String encodeString(String content){
 		
 		if(content==null || content.length()==0)
 			return null;
 		
 		int len = content.length();
 		
 		char[] cArray = new char[len + (int)Math.ceil(len/6.0d) + 1];
 		
 		if(BLUFF){
 			int s = 0;
 			int r = new Random().nextInt(26);
 			boolean u = ((r ^ len) & 1) == 1;
 			s = u ? 65 : 97;
 			cArray[0] = (char)(r + s);
 		}else{
 			cArray[0] = (char)DEF_SECRET;
 		}
 		
 		char c = '0';
 		int n = 0;
 		int mark = 0;
 		int pos = 0;
 		int segs = 0;
 		for(int i=0; i<len; i+=6){
 			mark = 1+i+segs;
 			for(int k=0; (k<6) && (pos<len); k++){
 				c = content.charAt(pos);
 				n = c ^ cArray[0]; 
 				n ^= k;
 				cArray[mark] |= ((n>>>6)<<k); 
 				
 				cArray[mark+k+1] = base_encode[n & MASK_64];
 				pos++;
 			}
 			segs++;
 			cArray[mark] = base_encode[cArray[mark]];
 		}
 		
 		return new String(cArray);
 		
 	}
 	
 	public static String encodeString(byte[] content){
 		
 		if(content==null || content.length==0)
 			return null;
 		
 		int len = content.length;
 		
 		char[] cArray = new char[len + (int)Math.ceil(len/6.0d) + 1];
 		
 		if(BLUFF){
 			int s = 0;
 			int r = new Random().nextInt(26);
 			boolean u = ((r ^ len) & 1) == 1;
 			s = u ? 65 : 97;
 			cArray[0] = (char)(r + s);
 		}else{
 			cArray[0] = (char)DEF_SECRET;
 		}
 		
 		byte c = 0;
 		int n = 0;
 		int mark = 0;
 		int pos = 0;
 		int segs = 0;
 		for(int i=0; i<len; i+=6){
 			mark = 1+i+segs;
 			for(int k=0; (k<6) && (pos<len); k++){
 				c = content[pos];
 				n = c ^ cArray[0]; 
 				n ^= k;
 				cArray[mark] |= ((n>>>6)<<k); 
 				
 				cArray[mark+k+1] = base_encode[n & MASK_64];
 				pos++;
 			}
 			segs++;
 			cArray[mark] = base_encode[cArray[mark]];
 		}
 		
 		return new String(cArray);
 		
 	}
 
  1. 解码方法
 	/** 解码 */
 	public static String decodeString(String content){
 		
 		if(content==null || content.length()==0)
 			return null;
 		
 		int len = content.length();
 		
 		char[] cArray = new char[len - 1 - (int)Math.ceil((len-1)/7.0)];
 		
 		char secret = content.charAt(0);
 		char c = '0';
 		int mark = 0;
 		int index = 0;
 		for(int i=1; i<len; i+=7){
 			mark = base_decode[content.charAt(i)];
 			for(int k=0, pos=i + k + 1; k<6 && pos<len; k++, pos++){
 				c = content.charAt(pos);
 //				cArray[index] = (char)((base_decode[c] + 64*((mark>>>k)&1)) k secret);
 				cArray[index] = (char)((base_decode[c] + (((mark>>>k)&1)<<6)) k secret);
 				index++;
 			}
 		}
 		
 		return new String(cArray);
 	}
 	
 	public static String decodeString(byte[] content){
 		
 		if(content==null || content.length==0)
 			return null;
 		
 		int len = content.length;
 		
 		char[] cArray = new char[len - 1 - (int)Math.ceil((len-1)/7.0)];
 		
 		byte secret = content[0];
 		byte c = 0;
 		int mark = 0;
 		int index = 0;
 		for(int i=1; i<len; i+=7){
 			mark = base_decode[content[i]];
 			for(int k=0, pos=i + k + 1; k<6 && pos<len; k++, pos++){
 				c = content[pos];
 				cArray[index] = (char)((base_decode[c] + (((mark>>>k)&1)<<6)) k secret);
 				index++;
 			}
 		}
 		
 		return new String(cArray);
 	}
 	
 	public static byte[] decodeBytes(byte[] content){
 		
 		if(content==null || content.length==0)
 			return null;
 		
 		int len = content.length;
 		
 		byte[] cArray = new byte[len - 1 - (int)Math.ceil((len-1)/7.0)];
 		
 		byte secret = content[0];
 		byte c = 0;
 		int mark = 0;
 		int index = 0;
 		for(int i=1; i<len; i+=7){
 			mark = base_decode[content[i]];
 			for(int k=0, pos=i + k + 1; k<6 && pos<len; k++, pos++){
 				c = content[pos];
 				cArray[index] = (byte)((base_decode[c] + (((mark>>>k)&1)<<6)) k secret);
 				index++;
 			}
 		}
 		
 		return cArray;
 	}
 	
 	public static byte[] decodeBytes(String content){
 		
 		if(content==null || content.length()==0)
 			return null;
 		
 		int len = content.length();
 		
 		byte[] cArray = new byte[len - 1 - (int)Math.ceil((len-1)/7.0)];
 		
 		byte secret = (byte)content.charAt(0);
 		byte c = 0;
 		int mark = 0;
 		int index = 0;
 		for(int i=1; i<len; i+=7){
 			mark = base_decode[content.charAt(i)];
 			for(int k=0, pos=i + k + 1; k<6 && pos<len; k++, pos++){
 				c = (byte)content.charAt(pos);
 				cArray[index] = (byte)((base_decode[c] + (((mark>>>k)&1)<<6)) k secret);
 				index++;
 			}
 		}
 		
 		return cArray;
 	}
 

Powered by Google Project Hosting