使用WireShark分析HTTP协议时几种常见的汉字编码
2016-09-20 23:28
363 查看
一、URL编码
编码实例:%E5%9B%9B%E5%B7%9D%E5%A4%A7%E5%AD%A6【下图中kw=之后,意为:四川大学】图1 使用百度贴吧客户端发表回复时的HTTP请求示例
常见位置:HTTP请求行中的URI(可能是请求静态网页时的中文路径、或是请求动态网页时的中文查询字符串)
HTTP请求正文中(当请求报文头部Content-Type头域的值为application/x-www-form-urlencoded时,如图1)
格式特点:以%开始,后面紧跟两个16进制数
编码解码:
这种编码方式由于最初用于使URL符合RFC 1738规范【RFC 1738中规定: “只有字母和数字[0-9,a-z,A-Z]、一些特殊符号“$-_.+!*'(),”[不包括双引号]、以及某些保留字,才可以不经过编码直接用于URL。”】而被称为URL编码,应该算是HTTP请求报文中最常见的编码了。
URL编码的过程很简单,如下:
将待编码字符原先的存储编码看成一个16进制流【将原2进制流按 字节拆分,每个字节都用2位16进制数表示】;
在每两位16进制数(即一个完整的字节)前加一个%,得到最终编码结果;
对于汉字来说,首先要看其本身存储时所使用的编码是UTF-8还是GB2312。同样的汉字,存储编码不同,经URL编码后的结果自然也不同。例如“川”,使用UTF-8编码存储时为e5b79d,经URL编码后则为%e5%b7%9d;使用GB2312编码存储时为b4a8,经URL编码后则为%b4%a8。
解码的时候也很简单,将编码里的%号去掉,得到一个16进制流,这个16进制流转回2进制流,得到的就是原字符的存储编码。剩下的一个重要问题是怎么理解这个还原出来的存储编码(即原字符使用的存储编码方式)?分三种情况:
对于HTTP请求正文中的URL编码,我们可以查看请求头部中Charset头域的值,它指定了请求报文所使用的字符集(即存储编码方式)。如图1,因为Charset的值为UTF-8,所以我们对解码后的结果就应当按UTF-8编码理解了;
因为使用UTF-8编码时,一个汉字的本身存储占三个字节;而使用GB2312编码,一个汉字的本身存储占两个字节。因此如果我们能确定被编码的是纯汉字流的话,我们可以根据解码后的结果占用的字节数是3或者2的倍数来大致推断其存储编码方式;
上述方法都不行的话,就只能在译码的时候都试一下了,但建议先试UTF-8。
解码工具:
百度上一搜一大堆,我经常用的是由九一网络开发的一个URL编码解码百度应用,地址是http://app.baidu.com/app/enter?appid=117335,用起来还比较方便。
二、Unicode编码【网上工具多称为UTF-8编码】
编码实例:\u6d6e\u751f\u82e5\u68a6【下图中深灰底色标注,意为:浮生若梦】图2 使用百度贴吧客户端查看“我的关注”时服务器给出的响应正文示例
常见位置:HTTP响应正文中
格式特点:以\u开始,后面紧跟四个16进制数
编码解码:
这种编码在网上多被称为UTF-8编码,其实是不太准确的。就其编码过程来看,编码时首先获取汉字对应的Unicode码,然后在Unicode码的前面加上\u就得到编码结果。每组由\u隔开的四个16进制数就对应一个汉字。
相应的,解码也很简单,只要挨个提取\u隔开的四个16进制数,以此作为Unicode编码值在UNICODE编码表里查找相应汉字即可。
解码工具:
114啦工具箱有个在线的UTF-8编码转换工具【地址是:http://tool.114la.com/site/utf8/】可以直接将这种编码转为汉字。我以前一直用的这个,但最近这个网站好像抽风了,上面好多工具都用不起了,不晓得啥时候恢复。
当前我用来解此类编码的是由站长工具提供的UTF-8编码转换工具【地址是:http://tool.chinaz.com/Tools/UTF-8.aspx】,这个工具以及很多其他类似工具的不好之处在于,他们对格式的要求太死板,如果把前述编码示例直接输入是解不出来的,必须先自行将之转换为形如浮生若梦 【将Unicode编码值前的\u替换为,并在Unicode编码值后加上半角分号】的样式才行。手工解码过程略嫌麻烦。
三、八进制显示编码
编码实例:\345\233\233\345\267\235\347\234\201【下图中浅灰色标注,意为四川省】图3 使用百度贴吧客户端定位时服务器给出的响应示例
常见位置:HTTP响应正文中
格式特点:以\开始,后面紧跟三个8进制数
编码解码:
这种编码其实并非是原始数据中实际存在的编码,它只是WireShark用以显示非ASCII字符的一种方式,所以我将之称之为显示编码。
如果你有C语言基础,那应该早就看到过,当然,在C语言的语法讲解中,这并不作为一种编码,而是归为转义字符的。
这种我所谓的显示编码,其编码规则类似于URL编码。他也是将待编码字符的存储编码按字节拆分,区别在于:
拆分后,每个字节的值用一个三位8进制数表示【URL编码中用二位16进制数表示】;
在每3位8进制数前加上一个反斜杆\【URL编码中在每2位16进制数前加上一个百分号%】
解码的时候,先将每3位8进制数转换成8为2进制数,然后将反斜杆去掉,得到的2进制流就是原字符的存储编码。
解码工具:
我还没有找到一个现成的,可以直接用的工具。一个可以偷懒的办法是,先用一个进制转换工具将3位8进制数转换为2位16进制数,再将所有反斜杆替换成百分号,这样这种编码就转成了URL编码,再利用前文说的URL编码解码百度应用,就可以完成手工解码了。
From:http://blog.csdn.net/howeverpf/article/details/9259835
------本文由CSDN-蚍蜉撼青松【主页:http://blog.csdn.net/howeverpf】原创,转载请注明出处!------
相关文章推荐
- 学习python写网络爬虫(三)
- SVProgressHUD网络延迟点击返回蒙板不消失的解决方案
- IP数据报的分片与重组
- 蚂蚁如何控制"运营开支"
- hdu 5876 - Sparse Graph(2016大连网络赛) bfs
- Android4种网络连接方式HttpClient、HttpURLConnection、OKHttp和Volley优缺点和性能对比
- hdu 5877 - Weak Pair (2016大连网络赛) 离散化 + 树状数组
- 【读书笔记】《数字图像处理》(第三版)[刚萨雷斯]-第12章 目标识别
- apt-get The method driver /usr/lib/apt/methods/http could not be found错误解决
- ReLU函数简介
- 浅谈HTTP中Get与Post的区别
- nodejs下载网络资源的三种方法写入数据
- HTTP协议中PUT和POST使用上的区别
- Java Socket编程之TCP协议
- java网络编程
- The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path
- 【Python开发】【神经网络与深度学习】如何利用Python写简单网络爬虫
- 【Python开发】【神经网络与深度学习】网络爬虫之图片自动下载器
- 【Python开发】【神经网络与深度学习】网络爬虫之python实现
- 安卓生成png背景变黑以及网络上一段可能误导的代码