zoukankan      html  css  js  c++  java
  • UTF-8与UNICODE的关系及代码转换

    http://blog.csdn.net/zonelive/article/details/544693

    今天在用fontforge改字体,因为UTF-8与UNICODE的关系,专门
    找了篇文章看,还写了几行代码验证自己的理解,并作为以后
    修改字体的工具,我把它命名为UTF82UNICODE及由UTF-8编码转
    换成UNICODE的意思,终于把UTF-8与UNICODE的关系基本搞清楚
    了,是为文,见后。


    所谓“utf-8”只是UCS Transformation Format,只是UNICODE
    的一种表现形式,不等同于UNICODE,一般汉字在UNICODE中为
    两个(双)字节表示,而我们看到实际保存的文档确是三个字
    节表示一个汉字的,看看下表:
    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
    UTF-8是一种变长度的表达方式,一般UNICODE为双字节(指UCS2)
    但为了与以前的ASCII码兼容,ASCII为一个字节,于是就想出
    了这种方法,在ASCII码的范围用一个字节表示,超出ASCII码
    的范围就用多字节表示,这就形成了我们上面看到的UTF-8的表
    示方法,这样的好处是当UNICODE文档中只有ASCII码时,保存
    的文档都为一个字节,所以就是普通的ASCII文档无异,读入的
    时候也是如此,所以能与以前的ASCII文档兼容。至于大于ASCII码的,就会由上面的第一字节的前几位表示该
    unicode字符的长度,比如110xxxxxx前三位的二进制表示告诉
    我们这是个2BYTE的UNICODE字符;1110xxxx是个三位的UNICODE
    字符,依此类推,而首字节后面的字节都是以10开头,见上面
    这是为了与ASCII码开头的0区分告诉我们这是个多字节UTF-8
    编码的后续位。看上面的编码,我们将上面的x部分重新连起来
    组成的数值就是实际的UNICODE码值了(排除10组成的标志位)。
    下面是个我写的从UTF-8转换到UNICODE真实值的程序,
    编译方法:
    gcc utf82unicode.cpp -o utf82unicode -lstdc++
    使用方法:
    比如一个汉字‘新’字,它的UTF-8编码为:E696B0,为了知道
    他的实际UNICODE编码,执行如下程序,
    ./utf82unicode E696B0
    unicode: 65B0
    上面程序的输出结果告诉我们UTF8:E696B0 对应UNICODE:65B0。

    附录:CPP程序utf82unicode.cpp

    #include
    #include

    // UTF-8的unicode表示方法到unicode的值转换函数
    bool utf82unicode(unsigned int byte[], int index, int count, int& unicode) {

    /* for (int i=index; i < count; ++i) { printf("byte[%d]:%0Xn",i, byte[i]); } printf("byte[index] & 0x80: %0Xn", byte[index] & 0x80); printf("byte[index] & 0xE0: %0Xn", byte[index] & 0xE0); printf("byte[index] & 0xF0: %0Xn", byte[index] & 0xF0); */ if (index >= count) return false; if ( (byte[index] & 0x80) == 0x0) // 一位 { unicode = byte[index]; } else if ((byte[index] & 0xE0) == 0xC0) // 两位 { if (index + 1 >= count ) return false; unicode = (((int)(byte[index] & 0x1F)) << 6) | (byte[ index + 1] & 0x3F); } else if ((byte[index] & 0xF0) == 0xE0) // 三位 { if (index + 2 >= count) return false; unicode = (((int)(byte[index] & 0x0F)) << 12) | (((int)(byte[index + 1] & 0x3F)) << 6) | (byte[index + 2] & 0x3F); } else if ((byte[index] & 0xF8) == 0xF0) // 四位 { if (index + 3 >= count) return false; unicode = (((int)(byte[index] & 0x07)) << 18) | (((int)(byte[index + 1] & 0x3F)) << 12) | (((int)(byte[index + 2] & 0x3F)) << 6) | (byte[index + 3] & 0x3F); } else if ((byte[index] & 0xFC) == 0xF8) // 五位 { if (index + 4 >= count) return false; unicode = (((int)(byte[index] & 0x03)) << 24) | (((int)(byte[index + 1] & 0x3F)) << 18) | (((int)(byte[index + 2] & 0x3F)) << 12) | (((int)(byte[index + 3] & 0x3F)) << 6) | (byte[index + 4] & 0x3F); } else if ((byte[index] & 0xFE) == 0xFC) // 六位 { if (index + 5 >= count) return false; unicode = (((int)(byte[index] & 0x01)) << 30) | (((int)(byte[index + 1] & 0x3F)) << 24) | (((int)(byte[index + 2] & 0x3F)) << 18) | (((int)(byte[index + 3] & 0x3F)) << 12) | (((int)(byte[index + 4] & 0x3F)) << 6) | (byte[index + 5] & 0x3F); } else { return false; } return true;

    }

    bool char2digist(char in, char&out)
    {

    if ('0' <= in && in <= '9') out = in - '0' + 0x0; else if ('A' <= in && in <= 'F') out = in - 'A' + 0xA; else if ('a' <= in && in <= 'f') out = in - 'a' + 0xa; else return false; return true;

    }

    bool widechar2hexbyte(char* ch, int index, int count, unsigned int& byte) {

    char h, l; if (index + 1 < count) { if (char2digist(ch[index], h) && char2digist(ch[index + 1], l)) { byte = ((unsigned int)(h << 4)) | l; return true; } } else { if (char2digist(ch[index], l)) { byte = l; return true; } } return false;

    }

    int main(int argc, char* argv[])
    {

    int bi, i, len, unicode; char* hex; unsigned int bytes[10]; if (argc < 2) { printf("usage: utf82unicode [hex string]n"); return 1; } bi = 0, len = strlen(argv[1]); // printf("argv[1]:%s,len:%dn", argv[1], len); for (int i = 0; i < len && bi < 10; ++ i) { if (!widechar2hexbyte(argv[1], i++, len, bytes[bi++])) return 1; } unicode = 0; if (utf82unicode(bytes, 0, bi, unicode)) { printf("unicode: %0Xn", unicode); return 0; } return 1; }
    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(4646) | 评论(0) | 转发(1) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    Unity 3(一):简介与示例
    MongoDB以Windows Service运行
    动态SQL中变量赋值
    网站发布IIS后堆栈追踪无法获取出错的行号
    GridView Postback后出错Operation is not valid due to the current state of the object.
    Visual Studio 2010 SP1 在线安装后,找到缓存在本地的临时文件以便下次离线安装
    SQL Server 问题之 排序规则(collation)冲突
    IIS 问题集锦
    linux下安装mysql(ubuntu0.16.04.1)
    apt-get update 系列作用
  • 原文地址:https://www.cnblogs.com/ztguang/p/12647194.html
Copyright © 2011-2022 走看看