应用层HTTP数据包的截获与还原技术(5)

4.3.2 捕获数据包的信息还原算法
在通过对数据包的分析得到还原文本信息所采用的编码方法后,根据得到的编码方法信息去解码当前要还原的信息。
1.
当获得的编码方法是GB2312
由于gb2312规定对任意一个图形字符都采用两个字节表示,每个字节均采用七位编码表示GB2312中汉字的编码范围为,第一字节0xB0-0xF7(对应十进制为176-247),第二个字节0xA0-0xFE(对应十进制为160-254)。
GB2312
将代码表分为94个区,对应第一字节(0xa1-0xfe);每个区94个位(0xa1-0xfe),对应第二字节,两个字节的值分别为区号值和位号值加322OH),因此也称为区位码。01-09区为符号、数字区,16-87区为汉字区(0xb0-0xf7),10-15区、88-94区是有待进一步标准化的空白区。
在编写gb2312解码算法的时候,算法思想是这样的,首先对转换后的前两位16进制数据进行判断,如果这两位十六进制数落在0xa1-0xfe内,则可以判断该编码是汉字编码的第一个字节,那么编码的第二个字节将是接下来的连续两个十六进制,因为汉字在gb2312编码标准中是采用两个字节编码的,根据这四个十六进制数位,我们就可以调用操作系统字库中gb2312编码表中对应的汉字;如果这两位十六进制数没有落在这样的范围内,则可判断是ASCALL码字符, ASCALL码是采用一个字节来编码的,这主要是英文、数字和常用字符,其解码程序很简单,在大部分编码标准都是固定的。将解码后的字符保存在字符串变量中,然后继续根据以上方法把所有编码转化为相应的字符,这样捕获的数据包的部分数据就全部可以还原为原始信息。
在程序实现算法时,为了让程序尽量简单,对于十六进制数的判断并没有在每个细节上去照顾,通过大量的实验数据表明,程序只是对与极个别的编码不能正确的识别,下图给出算法的流程图:

4.3
下面给出部分核心程序:
if(method=="gb2312")
{
for(int j=0;j<NUM;J++)
{
char c=hex[j].charAt(0);//
数组hex[]中每一个变量代//表两个十六进制的数位,在这之前已经初始化
switch(c)
{
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
{
count++;
if((count%2)!=0) //
如果在汉字字符范围则多取//一个字节
{
if(j<NUM-1)
{
String str=hex[j]+hex[j+1];//
两个字节16位,
result=result+d.DecodeGB2312(str);
//
调用程序的另一部分,这部分将调用字库中gb2312表中的响应字符
}
}
} break; default:result=result+d.DecodeAscII(hex[j]);break;
//
调用ASCALL解码程序,对编码进行解码还原
}
}
}
下图是gb2312编码字符解码还原结果:

4.4
2.
当获得的编码方法是utf-8
UNICODE
是一种国际通用编码,UNICODE是为了处理包括中文,日文等字符而提出的一种通用的字符集。最初的UNICODE为双字节字符集,即16位编码,能够包括65536个字符。但这样的容量并不能满足所有需要,因此,现在的UNICODE已经扩展到4个字节,能够容纳1,112,064 个字符,而这些在16位之后的扩展背称为增补字符。

编码字符集是一个字符集,它为每一个字符分配一个唯一数字。Unicode 标准的核心是一个编码字符集,字母“A”的编码为 0041 和字符“?”的编码为 20ACUnicode 标准始终使用十六进制数字,而且在书写时在前面加上前缀“U+”,所以“A”的编码书写为“U+0041”

代码点是指可用于编码字符集的数字。编码字符集定义一个有效的代码点范围,但是并不一定将字符分配给所有这些代码点。有效的 Unicode 代码点范围是 U+0000 U+10FFFFUnicode 4.0 将字符分配给一百多万个代码点中的 96,382 代码点。
增补字符是代码点在 U+10000 U+10FFFF 范围之间的字符,也就是那些使用原始的 Unicode 16 位设计无法表示的字符。从 U+0000 U+FFFF 之间的字符集有时候被称为基本多语言面 (BMP)。因此,每一个 Unicode 字符要么属于BMP,要么属于增补字符。
字符编码方案是从一个或多个编码字符集到一个或多个固定宽度代码单元序列的映射。最常用的代码单元是字节,但是 16 位或 32 位整数也可用于内部处理。UTF-32UTF-16 UTF-8 Unicode 标准的编码字符集的字符编码方案。(所谓编码方案可以视为具体的实现方案,即计算机内部的具体实现方案)
UTF-8
是能够兼容所有的客户访问端,是发展的方向,所以很多网站都开始采用了UTF-8编码规则进行编码。 UTF-8使用一至四个字节的序列对编码 Unicode 代码点进行编码。U+0000 U+007F 使用一个字节编码,U+0080 U+07FF 使用两个字节,U+0800 U+FFFF 使用三个字节,而 U+10000 U+10FFFF 使用四个字节。UTF-8 设计原理为:字节值 0x00 0x7F 始终表示代码点 U+0000 U+007FBasic Latin 字符子集,它对应 ASCII 字符集)。这些字节值永远不会表示其他代码点,这一特性使 UTF-8 可以很方便地在软件中将特殊的含义赋予某些 ASCII 字符。UFT-8转换表表示如下:

UNICODE
编码 UTF-8编码
00000000 - 0000007F 0xxxxxxx
00000080 - 000007FF 110xxxxx 10xxxxxx
00000800 - 0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
00010000 - 001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
00200000 - 03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
04000000 - 7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
4.2

由于UTF-8中汉字的编码集中采用三个字节编码,所以在解码的时候我们可以根据上面的三个字节编码规则对UTF-8编码进行解码。在解码的时候我们首先将十六进制转化为二进制,然后判断第一个字节编码,如果是以“1110”字符开始,那么可以确定该字节将是某一汉字编码的第一个字节的编码,再将接下来的四个连续十六进制数据一起传递到utf-8解码函数里,就可以在操作系统字库中能找到相应的汉字字符;如果转化后的二进制第一字节不是以“1110”开始,那么我们就默认采用ASCALL编码规则解码为英文字符等。在具体的程序编码时,为了简洁,就没有在对汉字编码字符的第二、三个字节给以判断。算法的流程图如下图所示:

4.5

以下是UTF-8部分解码核心程序。
if(method=="utf-8")
{
for(int j=0;j<NUM;J++)
{
char a=hex[j].charAt(0);
char b=hex[j].charAt(1);
switch(a)
{ //
将十六进制转化为二进制
case'0':h="0000";break;
case'1':h="0001";break;
case'2':h="0010";break;
………………//
省略了部分转化代码
case'F':h="1111";break;
}

if(h.startsWith("1110"))
{
String str=hex[j]+hex[j+1]+hex[j+2];
result=result+d.DecodeUTF(str); //
调用UTF-8解码函数
j+=2;
}

else
result=result+d.DecodeAscII(hex[j]);//
调用ASCALL解码函数
}
}
下图是UTF-8编码字符解码还原结果:

4.6
3.
当获得的编码方法是big5时,
big5
编码即繁体中文编码,每个汉字由两个字节构成,第一个字节的范围从0X810XFE(即129-255),共126种。第二个字节的范围不连续,分别为0X400X7E(即64-126),0XA10XFE(即161-254),共157种。
在对big5编码进行解码的时候,首先需要对编码的第一个十六进制位,如果其范围是“8F”;第二个范围是“1E”;第三个范围是“47”或是“AF”;第四个范围是“0E”或是“0E”,则可判断该编码是汉字字符,即可以采用big5解码程序调用字库中汉字字符。如果不满足汉字编码的范围将视为ASCALL编码字符,采用ASCALL解码程序解码。在具体的程序编写时,考虑到程序的简洁性,重点对第一字节的高四位和第二字节的高四位进行判断。算法的流程图如下图所示:

4.7
下面给出big5解码的部分核心程序。
if(method=="big5")
{
for(int j=0;j
{

char c=hex[j].charAt(0);
char e=hex[j].charAt(1);

switch(c)
{
case '8':
case '9':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
//
对第一字节的高四位进行判断
{
int i=j+1;
char u=hex.charAt(0);
char v=hex.charAt(1);
if(u>='4'&&u<='7'||u>='A'&&u<='F')
//
对第二字节的高四位进行判断
{
String str=hex[j]+hex; result=result+d.Decodebig5(str);
调用UTF-8解码函数
}
else
{
result=result+d.DecodeAscII(hex[j]);
result=result+d.DecodeAscII(hex);
}
++j;
} break; default:result=result+d.DecodeAscII(hex[j]);break; //
调用ASCALL解码函数

}
}
}
下图是big5编码字符解码还原结果:

4.8

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值