`

03_URL编码

 
阅读更多

一、URL编码相关知识

 

一、URL编码相关知识

首先来看一个URL编码的例子程序:

 

	public static void main(String[] args) throws Exception {
		String content = "中国";
		//这里将字符串转换成字节数组后的形式原样打印
		testPrintBytes(content);
		//d6d0b9fa
		System.out.println("=================");
		//这里打印URL编码后的字符串形式
		System.out.println(URLEncoder.encode(content,"GBK"));
		//%D6%D0%B9%FA
	}
	
	public static void testPrintBytes(String strContents) {
		byte[] byteArray = strContents.getBytes();
		for(int i=0; i<byteArray.length; i++) {
			printBytes(byteArray[i]);
		}
		System.out.println();
	}

        //输出字节的内存原样八位十六进制形式	
	public static void printBytes(byte byteData) {
			if(byteData > 0) {
				System.out.print(Integer.toHexString(byteData));
			}else {
				int temp = byteData & 255;
				System.out.print(Integer.toHexString(temp));
			}			
	}

 从打印出的内容来看,URL编码是将“中国”等不能出现在URL地址中的字符,以某种编码的二进制形式

 的每个字节前面加上“%”,并且将小写的字母编程大写的字母的过程。

不过从原理上来讲URL编码的过程还是比较复杂的,大致过程如下:

1、首先需要将字符串按照某种编码转换成字节数组的形式(这里我们指定的为GBK编码)

2、字节数组的原始内容为 d6d0b9fa
3、通过字节数组d6d0b9fa的内容,构造出URL编码字符串,

      这里我们自己来模拟该过程真正的实现未必就是这样,首先定义一个StringBuffer类型的URLBuffer和一个字符数组 chars={0123456789ABCDEF} 我们将十六进制的d6转换成二进制形式为 1101 0110 ,先将该字节高四位转换为一个字节 0000 1101  该字节的数值为13,然后将URLBuffer.append("%") 后再URLBuffer.append(chars[13]),然后将低四位作为一个字节得到 0000 0110 该字节的数值为6,然后URLBuffer.append(chars[6))  这样一来就得到了URL编码的 %D6 的字符串形式。

模拟过程代码如下:

	public static void main(String[] args) throws Exception {
		
		StringBuffer URLBuffer = new StringBuffer();
		char[] chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		String content = "中国";
		byte[] bytes = content.getBytes("GBK");
		for(int i=0; i<bytes.length; i++) {
			printBytes(bytes[i]);
		}
//输出 d6d0b9fa			
		System.out.println("");		
		for(int i=0; i<bytes.length; i++) {
			byte left4Bit = (byte)((bytes[i] >>> 4) & 15);
			byte right4Bit = (byte)(bytes[i] & 15);
			System.out.print(left4Bit + " ");
			System.out.print(right4Bit + " ");
			URLBuffer.append("%");
			URLBuffer.append(chars[left4Bit]);
			URLBuffer.append(chars[right4Bit]);
		}
//输出 13 6 13 0 11 9 15 10 		
		System.out.println("");
		
		System.out.println(URLBuffer.toString());
//输出 %D6%D0%B9%FA	
	}
	
	public static void printBytes(byte byteData) {
		if (byteData > 0) {
			System.out.print(Integer.toHexString(byteData));
		} else {
			int temp = byteData & 255;
			System.out.print(Integer.toHexString(temp));
		}
	}

 

URL编码的原则如下:

1、对于英文字母数字和*都是原样不进行编码的,例如:*,a,b,c,A,B,C, 0,1,2 等

2、URLEncoder.encode方法是按照HTML4.01的标准进行编码的。编码方式是根据ContextType的不同而区别对待的,在form的ContextType是[x-www-form-urlencoded]的时候会对form中的键/值对进行编码,空格被转义成+,其他字符按照[RFC1738]标准处理成%HH的形式。

加上了以上两条原则的模拟代码如下:

	public static void main(String[] args) throws Exception {
	
/*		String content = "中国&%abc *";
		//这里将字符串转换成字节数组后的形式原样打印
		testPrintBytes(content);
		//d6d0b9fa
		System.out.println("=================");
		//这里打印URL编码后的字符串形式
		System.out.println(URLEncoder.encode(content,"GBK"));
		//%D6%D0%B9%FA
*/		
		char a = 'a';
		System.out.println((int)a);
		
		StringBuffer URLBuffer = new StringBuffer();
		char[] chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
		String content = "中国abc* &";
		byte[] bytes = content.getBytes("GBK");
		for(int i=0; i<bytes.length; i++) {
			printBytes(bytes[i]);
		}
//输出 d6d0b9fa6162632a2026			
		System.out.println("");		
		for(int i=0; i<bytes.length; i++) {
			//这里实现字母数字和* 的原样输出
			if((bytes[i] >= 97 && bytes[i] <= 122) || (bytes[i] >= 65 && bytes[i] <= 90) || (bytes[i] >= 48 && bytes[i] <= 57) || bytes[i] == 42 ) {
				char c = (char)bytes[i];
				URLBuffer.append(c);
				System.out.print("-");
				continue;
			}
			
			//这里实现将" " 转换成"+"
			if(bytes[i] == 32) {
				URLBuffer.append("+");
				System.out.print("-");
				continue;
			}
			
			byte left4Bit = (byte)((bytes[i] >>> 4) & 15);
			byte right4Bit = (byte)(bytes[i] & 15);
			System.out.print(left4Bit + " ");
			System.out.print(right4Bit + " ");
			URLBuffer.append("%");
			URLBuffer.append(chars[left4Bit]);
			URLBuffer.append(chars[right4Bit]);
		}
//输出 13 6 13 0 11 9 15 10 -----2 6 		
		System.out.println("");
		
		System.out.println(URLBuffer.toString());
//输出 %D6%D0%B9%FAabc*+%26
		
	}
	
	public static void printBytes(byte byteData) {
		if (byteData > 0) {
			System.out.print(Integer.toHexString(byteData));
		} else {
			int temp = byteData & 255;
			System.out.print(Integer.toHexString(temp));
		}
	}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics