<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
4、文件删除和长目录项在文件目录表的格式
今天,我在SD上删除了文件bbb.txt,新建了一个《我的文档》文件夹,新建了一个“这是一个长文件名.txt”文件,然后利用sdrd命令读取该扇区,如下:
E5 B000 00 //前面共有64字节,两个E5打头的。
41 41 41 20 20 20 20 20 54 58 54 20 18 36 17 8B //文件aaa.txt。
<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />6F 3C6F3C 00 00 49 8B 6F3C 03 00 64 05 00 00 //在3号簇。
E5 B0 65 FA//前面共有64字节,两个E5打头的
E5 42 42 20 20 20 20 20 54 58 54 20 18 36 17 8B 6F3C6F3C
00 00 55 8B 6F3C 04 00 15 01 00 00 //这个就是被删除的bbb.txt文件,42被e5所取代。
E5 B0 65 FA 5E 20 00 87 //前面共有64字节,两个E5打头的
43 43 43 20 //文件ccc.txt。
20 20 20 20 54 58 54 20 18 36 17 8B 6F3C6F3C 00 00 61 8B
6F 3C 05 00 70 01 00 00
E5 B0 65 FA 5E 87 65 F6 4E 39 59 0F//前面共有64字节,两个E5打头的
31 31 31 20 20 20 20 20 //这是目录111
20 20 20 10 00 78 ED 98 70 3C 70 3C 00 00 EE 98 70 3C 06 00
00 00 00 00 //在6号扇区
E5 B0 65 FA 5E 87 65 F6 4E 39 59 0F 00 75 00 00 //前面共有64字节,两个E5
32 32 32 20 20 20 20 20 20 20 20 10 //这是目录222,在7号扇区
00 BB F4 98 70 3C 70 3C 00 00 F5 98 70 3C 07 00 00 00 00 00
41 11 62 84 76 87 65 63 68 00 00 0F 00 30 FF FF FF FF FF FF
FF FF FF FF FF FF 00 00 //蓝色表相应的长文件名,我6211的7684文6587档6863
CE D2 B5 C4 CE C4 B5 B5 //这是对应的短文件名,目录属性、在13号簇
20 20 20 10 00 1A 5D 7C 71 3C 71 3C 00 00 60 7C 71 3C0D 00
41 D9 8F2F 66 00 4E 2A 4E 7F 95 0F 00 EF 87 65 //这是一个长文
F6 4E 0D 54 2E 00 74 00 78 00 00 00 74 00 00 00 // 件名.txt
D5 E2 CA C7 //这是对应的短文件名,20表示档案文件,0E表示在14号簇
D2 BB 7E 31 54 58 54 20 00 87 67 7C 71 3C 71 3C 00 00 83 7C
71 3C0E 00 14 00 00 00 //14表示文件大小为20个字节
空目录我的文档是在13号簇,其首扇区=1976+(13-2)*8=2064。将这个扇区读出来如下:
2E 20 20 20 20 20 20 20 20 20 20 10 00 1A 5D 7C 71 3C 71 3C
00 00 60 7C 71 3C0D 00 00 00 00 00 2E 2E 20 20 20 20 20 20
20 20 20 10 00 1A 5D 7C 71 3C 71 3C 00 00 60 7C 71 3C 00 00
可见空目录下就只有点和点点两个文件夹。
“这是一个长文件名.txt”文件在14号簇,2072扇区,读出来如下:
CE D2 B5 C4 D0 C4 D6 D0 D3 D0 D2 BB B8 F6 C3 CE CF EB A1 A3总共20个字节,我当时往文件里写的好像是:我的心中有一个梦想。这是什么编码格式呢?
5、字符的编码格式
讲到字符的编码格式,已经接触到这么几个名词:ANSI、OEM、DBCS、Unicode、国标码、GBK、机内码、区位码,分别是什么含义呢?百度一下
ANSI , 这是美国国家标准协会制定的编码格式,例如"A汉" 在这种编码方式下的内存值为 41 BA BA ,'A'占用一个字节,"汉"用两个字节,记事本里用的好像就是ANSI编码。所以,ANSI = ASCII + 本地编码
GB2312,GBK,GB18030都是中国人自己发明的(中国之外并不使用的), 他们出现的时间顺序是GB2312 -> GBK -> GB18030 ,他们是包含关系,GB我猜是 "国标" 的意思 "k" 可能是 "扩展", 这些编码都是书面协议,要在计算机内部表示。所以GB2312的内存值须在原来的每个字节值(区位码)上加0x80得到机内码,加上0x80是为了使得每个字节的最高位为1,这样就可以在内存中区分汉字和ASCII了[因为ASCII的最高位都为0]. 但是后来要在GB2312上扩展(得到GBK,GB18030),就需要更多的编码空间,所以GBK,GB18030就没有要求第二个字节的的最高位为1了,而是通过第一个字节来判断这是一个字节的ASCII还是两个字节的GBK. GB2312、GBK都属于双字节字符集 (DBCS)。
所有的国标码汉字及符号组成一个94行94列的二维代码表中。在此方阵中,每一行称为一个"区",每一列称为一个"位"。这个方阵实际上组成一个有94个区(编号由01到94),每个区有94个位(编号由01到94)的汉字字符集。每两个字节分别用两位十进制编码,前字节的编码称为区码,后字节的编码称为位码,此即区位码,其中,高两位为区号,低两位为位号。
区位码 国标(GBK) 内码
"汉" 1A1A 3A3A BABA
国标 = 区位码 + 0x20 (每个字节)
内码 = 国标(GBK) + 0x80 (每个字节)
目前Windows的内核已经支持Unicode字符集,这样在内核上可以支持全世界所有的语言文字。但是由于现有的大量程序和文档都采用了某种特定语言的编码,例如GBK,Windows不可能不支持现有的编码,而全部改用Unicode。Windows使用代码页(code page)来适应各个国家和地区。code page可以被理解为前面提到的内码。GBK对应的code page是CP936。
输入码就是使用英文键盘输入汉字时的编码。目前,我国已推出的输入码有数百种,但用户使用较多的约为十几种,按输入码编码的主要依据,大体可分为顺序码、音码、形码、音形码四类,如“保”字,用全拼,输入码为码为“BAO”,用区位码,输入码为“1703”,用五笔字型则为“WKS”。
“这是一个长文件名.txt”文件在14号簇,2072扇区,读出来如下:
CE D2 B5 C4 D0 C4 D6 D0 D3 D0 D2 BB B8 F6 C3 CE CF EB A1 A3
61 62 63 64 65 66 67 2C31 32 33 34 35 36 37 2E 00 00 00 00,abcdefg和1234567是我后面修改后加的,说明这个编码不是unicode编码。因为汉字两个、英文一个编码,这应该就是acii码加上汉字国标机内码。
汉字我的编码是: CE D2减去80 80 后得到4e 52,应该是国标码,减去20 20 得到2E 32就是区位码。而我的unicode码是0x62 11=25105。若果造一个内码-unicode码转换表,应该是在第46区 50位。
2312转Unicode:
基于区位码计算编码库偏移地址,这个大家都做过,编码库的字节大小为2倍2312字库,库里只存Unicode码
Unicode转2312:
建立64K编码库(128K 字节,库里只存2312码, 不存在2312码的用0x0000补齐),用Unicode码的值做偏移地址直接查找对应的2312码,不用计算
中文字库就比较麻烦了。先取得汉字的内码,如使用GBK,‘上’的内码是0xc9,0xcf。在查到在对应字库中位置。取得该汉字的字库。
一般字库文件是按照GB 2312-80标准,也就是通常所说的国标码或区位码的标准排列的。国标码分为 94 个区(Section),每个区 94 个位(Position),所以也称为区位码。其中01~09 区为符号、数字区,16~87 区为汉字区。而 10~15 区、88~94 区是空白区域。 如何取得汉字的区位码呢?在计算机处理汉字和ASCII字符时,使每个ASCII字符占用1个字节,而一个汉字占用两个字节,其值称为汉字的内码。其中第一个字节的值为区号加上32(20H),第二个字节的值为位号加上32(20H)。为了与ASCII字符区别开,表示汉字的两个字节的最高位都是1,也就是两个字节的值都又加上了128(80H)。这样,通过汉字的内码,就可以计算出汉字的区位码。 具体算式如下: qh="c1-32-128"=c1-160 wh="c2-32-128"=c2-160 或 qh="c1-0xa0" wh="c2-0xa0" qh,wh为汉字的区号和位号,c1,c2为汉字的第一字节和第二字节。 根据区号和位号可以得到汉字字模在文件中的位置: location=(94*(qh-1)+(wh-1))*一个点阵字模的字节数。
5、有关字符编码的最后总结
上面有关编码的内容都是在百度上搜到的,我把重点标示了出来。我的收获是对于汉字在机内存储和如何显示的原理有了简单的了解。
我们在用输入法输入汉字的时候,看到了“真正的字”,但实际文件中一般只是存储的汉字内码。它如何让我们看到的呢?通过简单的转换得到区位码,区位码实际上指出了该汉字在字库文件中字符点阵储位置。通过获取点阵,在屏幕上显示汉字。
有时候,汉字在内部以unicode码的格式存储,比如文件系统中长文件名,都是这样。那我们要操作文件系统,怎么样才能由内码得到unicode码呢?这个可以用一张转换表来实现,这张表可以以汉字区位表为基础,共需要94*94*2这么大,大概20K左右。
如果要显示文件系统中汉字命名的文件,需要先由unicode码得到内码,然后再获取字型数据显示,这时也可以用一张表,但这个表稍微大一些,因为unicode有65536个,这张表需要128k大。
文章评论(0条评论)
登录后参与讨论