.NET 的编码

 

字符集和编码方式

字符集(Charset):是一个系统支持的所有抽象字符的集合。字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。

字符编码(Character Encoding):是一套法则,使用该法则能够对自然语言的字符的一个集合(如字母表或音节表),与其他东西的一个集合(如1~65535之间的数字)进行配对。计算机所谓编码就是把A这样的字符和数字建立一个对应关系。

GB2312,ASCII这些既是字符集又是编码方式的大家都容易理解。unicode稍微复杂一点。unicode是一个UCS通用字符集,包含所有国家语言的字符,比如中文字符,日文字符,这些字符都对应一个编号比如A的编号是U+0041,0041是十六进制。UCS只是规定如何编码,并没有规定如何传输、保存这个编码。又例如“汉”字的UCS编码是6C49,我可以用4个数字来传输、保存这个编码;也可以用utf-8编码:3个连续的字节E6 B1 89来表示它。关键在于通信双方都要认可。UTF-8、UTF-7、UTF-16都是被广泛接受的方案。UTF-8的一个特别的好处是它与ISO-8859-1完全兼容。

事情本来很清楚,但是微软系统里面的一些称呼让人很困扰,注意分清楚:

在 Windows 记事本的语境中:
所谓的「ANSI」指的是对应当前系统 locale 的遗留(legacy)编码。
所谓的「Unicode」指的是带有 BOM 的小端序 UTF-16。
所谓的「UTF-8」指的是带 BOM 的 UTF-8。

比如在记事本里面写“A汉”,如果存成 unicode就是FF FE 41 00 49 6C ,FF FE是BOM,表示汉字的汉室496C而不是6C49

存成UTF-8就是EF BB BF 41 E6 B1 89 ,EF BB BF就是BOM,BOM本来用来表示顺序,对于UTF-8没有什么必要呢

 

程序里的字符与字节

.NET中有表示字符的类char,有表示字节的类byte。char 代表一个UNICODE 字符,而byte表示一个8bit位。有同学会问这个char类型是怎么实现的呢,比如字符A是用什么方式表示呢?

在.NET内部用utf16编码方式,即两个字节来表示ucs,表示65535个不同的字符,基本覆盖了人们常用的字符。比如A 在char里用两个字节0x4100来表示。“中”用两个字节0x2d4e来表示。需要说的是,尽管utf8和utf16都是用来编码unicode字符集,但是他们同样字符用的表示字节可能完全不同。utf8时变长的,“中”用三个字节0xe4 b8 ad来表示。utf16时定长,定位非常方便,估计这也是被选作内部编码的原因。

 

下面是一个简单的控制台程序,program.cs文件,这个文件本身默认是utf8编码,

 

 class Program
    {
        static void Main(string[] args)
        {
            string teststr = "中123";

            var asciibytes = Encoding.ASCII.GetBytes(teststr);

            var utf8bytes = Encoding.UTF8.GetBytes(teststr);

            var defaultbytes = Encoding.Default.GetBytes(teststr);
  
            Console.WriteLine(teststr.Length);
            

            string str = "\u24c8 \u2075 \u221e";
            Console.WriteLine("Original string: " + str);
        }
}    

 

 MS Build 会以UTF-8读取文件,编译。在执行的时候,

string teststr = "中123";

声明一个字符串变量,内存里面是UTF-16的0x 2D4E 3100 3200 3300

 

posted on 2015-06-25 14:25  eason_wang  阅读(255)  评论(0编辑  收藏  举报

导航