字符编码

一般情况

复制代码
            string hello = "hello你好";

            var helloArray1 = Encoding.UTF8.GetBytes(hello);
            Console.WriteLine(helloArray1.Length);

            var helloArray2 = Encoding.Unicode.GetBytes(hello);
            Console.WriteLine(helloArray2.Length);

            var helloArray3 = Encoding.ASCII.GetBytes(hello);
            Console.WriteLine(helloArray3.Length);

            var helloArray4 = Encoding.UTF7.GetBytes(hello);
            Console.WriteLine(helloArray4.Length);
            
            var helloArray5 = Encoding.UTF32.GetBytes(hello);
            Console.WriteLine(helloArray5.Length);
复制代码

Length of byte array for hello你好 in System.Text.ASCIIEncoding is 7
Length of byte array for hello你好 in System.Text.UnicodeEncoding is 14
Length of byte array for hello你好 in System.Text.UTF32Encoding is 28
Length of byte array for hello你好 in System.Text.UTF8Encoding is 11
Length of byte array for hello你好 in System.Text.UTF7Encoding is 13


上面的输出结果,

UTF8得到的字节数组长度是5*1+2*3=11           

Unicode得到的字节数组长度是7*2=14

ASCII得到的字节数组长度是7*1=7

UTF7得到的字节数组长度是5*1+2*4=13

UTF32得到的字节数组长度是7*4=28

总结:ASCII按照1个字符,1个字节来算。

           Unicode按照1个字符,2个字节来计算。

           UTF32,按照1个字符,4个字节来计算

           UTF8,如果1个字符可以用1个字节表示,就用一个字节表示;否则就用3个字节表示。

           UTF7,

          

 

特殊情况

1个字符,本身就占据4个字节

复制代码
        [Test]
        public void Test7()
        {
            string hello = "\U0001D11E";

            OutputLengthOfByteArray(hello, Encoding.ASCII);
            OutputLengthOfByteArray(hello, Encoding.Unicode);
            OutputLengthOfByteArray(hello, Encoding.UTF32);
            OutputLengthOfByteArray(hello, Encoding.UTF8);
            OutputLengthOfByteArray(hello, Encoding.UTF7);
        }

        public void OutputLengthOfByteArray(string input,Encoding encoding)
        {
            var array = encoding.GetBytes(input);
            Console.WriteLine($"Length of byte array for {input} in {encoding} is {array.Length}");
        }
复制代码

Length of byte array for 𝄞 in System.Text.ASCIIEncoding is 2
Length of byte array for 𝄞 in System.Text.UnicodeEncoding is 4
Length of byte array for 𝄞 in System.Text.UTF32Encoding is 4
Length of byte array for 𝄞 in System.Text.UTF8Encoding is 4
Length of byte array for 𝄞 in System.Text.UTF7Encoding is 8

 

 

 

扩展阅读

http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html

UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

UTF-8的编码规则很简单,只有二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。

2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

 http://www.cnblogs.com/chucklu/p/5231872.html

 

刹那芳华曲对应的Unicode十六进制  二进制

刹5239    0101 0010 0011 1001
那90A3    1001 0000 1010 0011
芳82B3
华534E
曲66F2

严4E25

 

复制代码
 [Test]
        public void Test2()
        {
            string input = @"严";
            List<ushort> list = new List<ushort>();
            foreach (var item in input)
            {
                list.Add(item);
            }
            foreach (var item in list)
            {
                Console.WriteLine($"{item:X2}");
            }
        }
复制代码

 

 

 

严对应的UTF-8的十六进制为E4 B8 A5

  var array= Encoding.UTF8.GetBytes(input);
            string str = GetHexStringFromByteArray(array);
            Console.WriteLine(str);

private string GetHexStringFromByteArray(byte[] array)
        {
            return string.Join(" ", array.Select(x => x.ToString("X2")));
        }

 

刹那芳华曲对应的UTF-8的十六进制

E5 88 B9

E9 82 A3

E8 8A B3

E5 8D 8E

E6 9B B2

复制代码
   [Test]
        public void Test2()
        {
            string input = @"刹那芳华曲";
            var array= Encoding.UTF8.GetBytes(input);
            string str = GetHexStringFromByteArray(array);
            Console.WriteLine(str);
        }

        private string GetHexStringFromByteArray(byte[] array)
        {
            return string.Join(" ", array.Select(x => x.ToString("X2")));
        }
复制代码

 

E5 88 B9 E9 82 A3 E8 8A B3 E5 8D 8E E6 9B B2
11100101 10001000 10111001    

第一个字节的前3位都是1,说明这个字符占3个字节。剩下的2个字节,都以10开头。 没有提及的二进制位,是Unicode的二进制。

00101001000111001  这个对应到Unicode的0x5239

11101001 10000010 10100011

11101000 10001010 10110011

11100101 10001101 10001110

11100110 10011011 10110010

复制代码
  [Test]
        public void Test2()
        {
            string input = @"刹那芳华曲";
            var array= Encoding.UTF8.GetBytes(input);
            string strHex = GetHexStringFromByteArray(array);
            Console.WriteLine(strHex);
            string strBinary = GetBinaryStringFromByteArray(array);
            Console.WriteLine(strBinary);
        }

        private string GetHexStringFromByteArray(byte[] array)
        {
            return string.Join(" ", array.Select(x => x.ToString("X2")));
        }

        private string GetBinaryStringFromByteArray(byte[] array)
        {
            return string.Join(" ", array.Select(x => Convert.ToString(x, 2).PadLeft(8, '0')));
        }
复制代码

 

Unicode To UTF8 及编码过程实时解析

 

作者:Chuck Lu    GitHub    
posted @   ChuckLu  阅读(686)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2015-07-12 Which are in?
2015-07-12 IQ Test
2015-07-12 string.Split函数
点击右上角即可分享
微信分享提示