用于从char到byte的强制转换的编码

时间:2012-05-22 19:13:06

标签: c# character-encoding casting

查看以下C#代码(从http://wmsauth.org/examples中的BuildProtectedURLWithValidity函数中提取的函数):

byte[] StringToBytesToBeHashed(string to_be_hashed) {
    byte[] to_be_hashed_byte_array = new byte[to_be_hashed.Length];
    int i = 0;
    foreach (char cur_char in to_be_hashed)
    {
        to_be_hashed_byte_array[i++] = (byte)cur_char;
    }
    return to_be_hashed_byte_array;
}

我的问题是:在编码方面从字节到字符的转换是什么?

我猜它在编码方面确实没有任何作用,但这是否意味着Encoding.Default是使用的那个,因此返回的字节将取决于框架将如何编码特定Operative中的底层字符串系统

此外,char实际上大于一个字节(我猜2个字节)并且实际上会省略第一个字节?

我正在考虑通过以下方式取代所有这些:

Encoding.UTF8.GetBytes(stringToBeHashed)

您怎么看?

3 个答案:

答案 0 :(得分:15)

.NET Framework使用Unicode来表示其所有字符和字符串。 char的整数值(可以通过强制转换为int获得)等同于其UTF-16代码单元。对于基本多语言平面中的字符(构成您将遇到的大多数字符),此值是Unicode代码点。

  

.NET Framework使用Char结构来表示Unicode字符。 Unicode标准使用称为代码点的唯一21位标量数来标识每个Unicode字符,并定义UTF-16编码格式,该格式指定如何将代码点编码为一个或多个16位值的序列。每个16位值的范围从十六进制0x00000xFFFF,并存储在Char结构中。 Char对象的值是其16位数字(序数)值。 - Char Structure

char投射到byte会导致任何值大于255的字符丢失数据。尝试运行以下简单示例来了解原因:

char c1 = 'D';        // code point 68
byte b1 = (byte)c1;   // b1 is 68

char c2 = 'ń';        // code point 324
byte b2 = (byte)c2;   // b2 is 68 too!
                      // 324 % 256 == 68

是的,你绝对应该使用Encoding.UTF8.GetBytes

答案 1 :(得分:4)

bytechar之间的转换就像使用ISO-8859-1编码(= Unicode的前256个字符),除了在编码超出U + 00FF的字符时静默丢失信息。< / p>

  

此外,char实际上大于一个字节(我猜2个字节)并且实际上会省略第一个字节?

是。 C#char = UTF-16代码单元= 2个字节。

答案 2 :(得分:1)

char表示16位UTF-16代码点。将char投射到byte会导致角色的低位字节,但 Douglas dan04 都是错误的,因为它总是会安静地丢弃较高的字节。如果高字节不为零,则结果取决于是否设置了编译器选项检查算术溢出/下溢

using System;
namespace CharTest
{
    class Program
    {
        public static void Main(string[] args)
        {   ByteToCharTest( 's' );
            ByteToCharTest( 'ы' );

            Console.ReadLine();
        }

        static void ByteToCharTest( char c )
        {   const string MsgTemplate =
                "Casting to byte character # {0}: {1}";

            string msgRes;
            byte   b;

            msgRes = "Success";
            try
            {   b = ( byte )c;  }
            catch( Exception e )
            {   msgRes = e.Message;  }

            Console.WriteLine(
                String.Format( MsgTemplate, (Int16)c, msgRes ) );
        }
    }
}

溢出检查输出:

Casting to byte character # 115: Success
Casting to byte character # 1099: Arithmetic operation resulted in an overflow.

没有溢出检查的输出:

Casting to byte character # 115: Success        
Casting to byte character # 1099: Success