网址的url编码解码讲解
2018-01-04 17:39
211 查看
问题
这是某个网站url的编码,也就是网址所显示的字符。%E8%AF%84%E8%AE%BA%E7%AE%A1%E7%90%86
原来的内容是
评论管理
原理说明
这实际上是url的字符进行encode编码操作,想知道原来的内容是什么则将其decode解码即可。如
评论管理进行encode编码操作变成
%E8%AF%84%E8%AE%BA%E7%AE%A1%E7%90%86,
%E8%AF%84%E8%AE%BA%E7%AE%A1%E7%90%86进行decode解码即可得到
评论管理
API说明
JAVA的url编码解码API说明URLEncoder.encode(input,”utf-8”):将字符串input使用utf-8编码方式进行url编码。
URLDecoder.decode(output,”utf-8”):将字符串output使用utf-8进行url解码
API使用代码
String input = "评论管理 abcefg"; String output = URLEncoder.encode(input,"utf-8"); String restore = URLDecoder.decode(output,"utf-8"); System.out.println(output); System.out.println(restore);
执行结果:
%E8%AF%84%E8%AE%BA%E7%AE%A1%E7%90%86+abcefg 评论管理 abcefg
Java实现原理说明
这里以URLEncoder.encode进行讲解,URLEncoder.encode方法里使用了BitSet类。encode方法内首先对Bitset类进行初始化,将大小写字母(a~z,A~Z)、数字(0~9)、空格( )、下划线(_)、中划线(-)、点(.)、星号(*)通过Bitset的set方法加入到符号集中。
执行encode方法时,对输入的字符串s进行遍历,如果s[i]在字符集里,空格转化为+,其余的保持不变,然后加到out数组;
若s[i]不在字符集内,则把连续不在字符集的字符拼接起来,获取其字节数组,然后通过Character.forDigit((ba[j] >> 4) & 0xF, 16)进行编码,最后拼接到out数组,详细内容可以查看下面的代码讲解。
部分代码和讲解
encode方法中BitSet初始化的代码static BitSet dontNeedEncoding; static { dontNeedEncoding = new BitSet(256); int i; for (i = 'a'; i <= 'z'; i++) { dontNeedEncoding.set(i); } for (i = 'A'; i <= 'Z'; i++) { dontNeedEncoding.set(i); } for (i = '0'; i <= '9'; i++) { dontNeedEncoding.set(i); } dontNeedEncoding.set(' '); /* encoding a space to a + is done * in the encode() method */ dontNeedEncoding.set('-'); dontNeedEncoding.set('_'); dontNeedEncoding.set('.'); dontNeedEncoding.set('*'); dfltEncName = AccessController.doPrivileged( new GetPropertyAction("file.encoding") ); }
encode方法讲解
// 输入s , 编码enc public static String encode(String s, String enc) throws UnsupportedEncodingException { // 标记是否需要转化 boolean needToChange = false; // 将需要编码的字符串缓冲到StringBuffer StringBuffer out = new StringBuffer(s.length()); Charset charset; CharArrayWriter charArrayWriter = new CharArrayWriter(); // 抛出编码为空的异常 if (enc == null) throw new NullPointerException("charsetName"); try { // 设置编码 charset = Charset.forName(enc); } catch (IllegalCharsetNameException e) { throw new UnsupportedEncodingException(enc); } catch (UnsupportedCharsetException e) { throw new UnsupportedEncodingException(enc); } for (int i = 0; i < s.length();) { int c = (int) s.charAt(i); // 是否在设置的字符集里面 if (dontNeedEncoding.get(c)) { // 空格设置为+,其他的不变 if (c == ' ') { c = '+'; needToChange = true; } out.append((char)c); i++; } else { // 当出现不在字符集里的字符,开始遍历,将不在字符集里的字符加到charArrayWriter,直到出现在字符里的字符时停止遍历 do { charArrayWriter.write(c); if (c >= 0xD800 && c <= 0xDBFF) { if ( (i+1) < s.length()) { int d = (int) s.charAt(i+1); // utf-16的高位区 if (d >= 0xDC00 && d <= 0xDFFF) { charArrayWriter.write(d); i++; } } } i++; } while (i < s.length() && !dontNeedEncoding.get((c = (int) s.charAt(i)))); // 清空charArrayWriter的内容 charArrayWriter.flush(); String str = new String(charArrayWriter.toCharArray()); // 获取字节数组 byte[] ba = str.getBytes(charset); // 遍历数组,将编码后的字符加到out中,其中caseDiff是大小写字符的距离('a' - 'A') for (int j = 0; j < ba.length; j++) { out.append('%'); char ch = Character.forDigit((ba[j] >> 4) & 0xF, 16); // converting to use uppercase letter as part of // the hex value if ch is a letter. if (Character.isLetter(ch)) { ch -= caseDiff; } out.append(ch); ch = Character.forDigit(ba[j] & 0xF, 16); if (Character.isLetter(ch)) { ch -= caseDiff; } out.append(ch); } charArrayWriter.reset(); needToChange = true; } } // 如果转化过,则输出out,否则输出原来的字符串即可 return (needToChange? out.toString() : s); }
相关文章推荐
- 详解JavaScript中的Url编码/解码,表单提交中网址编码
- 网址url编码和解码
- php url编码与解码(加/解密)
- javascript的URL编码和解码
- asp.net UrI URL编码解码
- (转载)URL编码与解码
- 一个URL编码和解码的C++类
- C#实现Url编码和解码
- 本文以H264视频流为例,讲解解码流数据的步骤。
- URL编码与解码&escape, encodeURI和encodeURIComponent区别
- ffmpeg 编解码有用网址
- Web开发须知:URL编码与解码
- URL编码与解码
- ios对于字符串的url编码和解码问题
- ORACLE使用UTL_URL包对字符串进行URL编码解码
- ASP.NET中的URL编码解码
- URL编码与解码
- 好的视频编解码网址和博文地址
- iOS URL编码与解码