字符编码

一般情况

            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 及编码过程实时解析

 

posted @ 2017-07-12 21:30  ChuckLu  阅读(689)  评论(0)    收藏  举报