zoukankan      html  css  js  c++  java
  • 若干编码说明

    一、gb2312
    现在我们大部分的中国程序员编译的程序可执行代码中包含的都是gb2312编码,这些编码通常体现在代码中的字符串里。编译器对于这些字符串的内容并不做特殊解释,因为gb2312中的常用英文字符是和ASCII码兼容的。
    根据编码的约定,通常的前32个字符是作为控制字符,也就是无法在屏幕上直接对应一个可显示的字符,它们的范围在0x00-0x20之间,再往上的0x20到0x7f通常认为是可显示的字符。共96个字符,但是汉字编码中对于这个区间的第一个和最后一个都没有使用,也就是合法区间是从0x21--0xFE,共94个字符。大家可以看到,此时的ascii编码只是用了8个字节中的7个,0x80以上的没有在ascii码中定义,此时不同的编码就会对这些内容进行解释。
    和低128编码大致分区类似,此时的0x80开始到0xA0依然作为非显示的控制字符使用,剩余的96个作为显示字符。gb2312编码时就使用了这些0xA)开始的编码,只是它们是由两个连续的字节组成一个汉字。这是ascii码的编码规则,而对于汉字来说,它的划分更偏重于逻辑的划分,它只是简单的将这些汉字划分为不同的区,每个区总共94个汉字。当用内码表示一个汉字时,只需将其区位编码和区内编码各自加上0xA0即可。它的优点是可以和ascii编码完全兼容。
    二、utf-8编码
    unicode编码的时候和IPV4到IPV6的扩展一样,使用了足够大的空间,优点是可以表示所有的字符,但是缺点就是对于ascii码,它存在大量的0字节,这些字节无论对存储还是传输来说都是极大的浪费,所以此时有了utf-8编码,它存在的意义同样是为了兼容ascii码编码不变,从而满足大部分英语语系国家的传输。
    这个编码使用的是非常简单的前缀码编码格式,它通过开始的1的个数来确定自己包含的真正有效负载数量,并且保证不同的负载可以互相区分。
    wiki中对于该编码的说明

    Unicode和UTF-8之间的转换关系表
    UCS-4编码    UTF-8字节流
    U+00000000 – U+0000007F    0xxxxxxx
    U+00000080 – U+000007FF    110xxxxx 10xxxxxx
    U+00000800 – U+0000FFFF    1110xxxx 10xxxxxx 10xxxxxx
    U+00010000 – U+001FFFFF    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
    U+00200000 – U+03FFFFFF    111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    U+04000000 – U+7FFFFFFF    1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
    可以看到,它完全兼容了ascii码,所有的编码最高位都不是零,从而区分了unicode的字符和常规ascii编码。第一个字节可以确定之后字节的长度,并且和ascii码(0开始字符)、中间码(10开始字符)均没有重合。
    三、不同编码之间的转换
    通常的文件并不在意字符的编码,但是在显示的过程中可能需要进行特殊的转换,这些转换在linux系统中通过一组iconv函数完成,基本的接口为iconv_open、iconv和iconv_close,这的确是一个经典的三元组组合,它们和正则表达式的三个基本操作语义相同。
    这组转换和内核没有关系,C库完全可以独立完成,我们通过
    strace iconv --list
    可以大致知道这个库文件保存在
    [root@Harry thiscast]# ll /usr/lib/gconv/
    total 6264
    -rwxr-xr-x. 1 root root  19840 2010-10-23 02:07 ANSI_X3.110.so
    -rwxr-xr-x. 1 root root  11440 2010-10-23 02:07 ARMSCII-8.so
    -rwxr-xr-x. 1 root root  11488 2010-10-23 02:07 ASMO_449.so

    文件夹,其中有一个不同字符集合之间转换的配置文件gconv-modules,其中定义了可以转换的文件以及大量转换的so,它们这些so中一般包含了转换的函数和转换时映射的字库数据库,上层的iconv接口会通过特定的结构找到这些so中的函数并将用户输入的编码转换为目标格式编码。
    四、glibc中相关实现
    glibc-2.7iconv文件中包含了iconv函数族实现及其它功能性代码,其它数据库性质的文件则保存在glibc-2.7iconvdata文件夹下。这个转换的过程应该是由makefile完成,但是现在没有兴趣和时间来分析它的实现。但是可以摘录一下其中的一些片段glibc-2.7iconvdatagb2312.c:

    /* The conversion table to UCS4 has almost no holes.  It can be generated with:

       egrep '^0x' /mnt/cdrom/unix/mappings/eastasia/gb/gb2312.txt |
       perl tab.pl

       where tab.pl is:
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       $n=0;
       while (<>) {
         local($gb, $ucs4, %rest) = split;
         local($u)=hex($ucs4);
         local($g)=hex($gb);
         printf (" ") if ($n % 4 eq 0);
         ++$n;
         printf (" [0x%04x] = 0x%04x,",
                 int(($g - 0x2121) / 256) * 94 + (($g - 0x2121) & 0xff), $u);
       }
       printf (" ");
       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
     */
    const uint16_t __gb2312_to_ucs[] =
    {
      [0x0000] = 0x3000, [0x0001] = 0x3001, [0x0002] = 0x3002, [0x0003] = 0x30fb,
      [0x0004] = 0x02c9, [0x0005] = 0x02c7, [0x0006] = 0x00a8, [0x0007] = 0x3003,
      [0x0008] = 0x3005, [0x0009] = 0x2015, [0x000a] = 0xff5e, [0x000b] = 0x2016,
      [0x000c] = 0x2026, [0x000d] = 0x2018, [0x000e] = 0x2019, [0x000f] = 0x201c,
      [0x0010] = 0x201d, [0x0011] = 0x3014, [0x0012] = 0x3015, [0x0013] = 0x3008,
      [0x0014] = 0x3009, [0x0015] = 0x300a, [0x0016] = 0x300b, [0x0017] = 0x300c,
      [0x0018] = 0x300d, [0x0019] = 0x300e, [0x001a] = 0x300f, [0x001b] = 0x3016,
      [0x001c] = 0x3017, [0x001d] = 0x3010, [0x001e] = 0x3011, [0x001f] = 0x00b1,
      [0x0020] = 0x00d7, [0x0021] = 0x00f7, [0x0022] = 0x2236, [0x0023] = 0x2227,
      [0x0024] = 0x2228, [0x0025] = 0x2211, [0x0026] = 0x220f, [0x0027] = 0x222a,
      [0x0028] = 0x2229, [0x0029] = 0x2208, [0x002a] = 0x2237, [0x002b] = 0x221a,
      [0x002c] = 0x22a5, [0x002d] = 0x2225, [0x002e] = 0x2220, [0x002f] = 0x2312,
      [0x0030] = 0x2299, [0x0031] = 0x222b, [0x0032] = 0x222e, [0x0033] = 0x2261,
      [0x0034] = 0x224c, [0x0035] = 0x2248, [0x0036] = 0x223d, [0x0037] = 0x221d,
      [0x0038] = 0x2260, [0x0039] = 0x226e, [0x003a] = 0x226f, [0x003b] = 0x2264,
      [0x003c] = 0x2265, [0x003d] = 0x221e, [0x003e] = 0x2235, [0x003f] = 0x2234,
      [0x0040] = 0x2642, [0x0041] = 0x2640, [0x0042] = 0x00b0, [0x0043] = 0x2032,
      [0x0044] = 0x2033, [0x0045] = 0x2103, [0x0046] = 0xff04, [0x0047] = 0x00a4,
      [0x0048] = 0xffe0, [0x0049] = 0xffe1, [0x004a] = 0x2030, [0x004b] = 0x00a7,
      [0x004c] = 0x2116, [0x004d] = 0x2606, [0x004e] = 0x2605, [0x004f] = 0x25cb,
      [0x0050] = 0x25cf, [0x0051] = 0x25ce, [0x0052] = 0x25c7, [0x0053] = 0x25c6,
      [0x0054] = 0x25a1, [0x0055] = 0x25a0, [0x0056] = 0x25b3, [0x0057] = 0x25b2,
      [0x0058] = 0x203b, [0x0059] = 0x2192, [0x005a] = 0x2190, [0x005b] = 0x2191,
      [0x005c] = 0x2193, [0x005d] = 0x3013, [0x006e] = 0x2488, [0x006f] = 0x2489,
      [0x0070] = 0x248a, [0x0071] = 0x248b, [0x0072] = 0x248c, [0x0073] = 0x248d,
      [0x0074] = 0x248e, [0x0075] = 0x248f, [0x0076] = 0x2490, [0x0077] = 0x2491,
      [0x0078] = 0x2492, [0x0079] = 0x2493, [0x007a] = 0x2494, [0x007b] = 0x2495,
      [0x007c] = 0x2496, [0x007d] = 0x2497, [0x007e] = 0x2498, [0x007f] = 0x2499,
      [0x0080] = 0x249a, [0x0081] = 0x249b, [0x0082] = 0x2474, [0x0083] = 0x2475,

  • 相关阅读:
    [转发]深入理解git,从研究git目录开始
    iOS系统网络抓包方法
    charles抓包工具
    iOS多线程中performSelector: 和dispatch_time的不同
    IOS Core Animation Advanced Techniques的学习笔记(五)
    IOS Core Animation Advanced Techniques的学习笔记(四)
    IOS Core Animation Advanced Techniques的学习笔记(三)
    IOS Core Animation Advanced Techniques的学习笔记(二)
    IOS Core Animation Advanced Techniques的学习笔记(一)
    VirtualBox复制CentOS后提示Device eth0 does not seem to be present的解决方法
  • 原文地址:https://www.cnblogs.com/tsecer/p/10487475.html
Copyright © 2011-2022 走看看