7

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

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;
}

我的问题是:从 byte 到 char 的转换在编码方面有什么作用?

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

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

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

Encoding.UTF8.GetBytes(stringToBeHashed)

你怎么看?

4

3 回答 3

17

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

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

转换charbyte将导致值大于 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

于 2012-05-22T19:18:47.553 回答
4

byte在and之间转换char类似于使用ISO-8859-1编码(= Unicode 的前 256 个字符),除了在编码超过 U+00FF 的字符时它会默默地丢失信息。

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

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

于 2012-05-22T19:26:00.217 回答
1

char表示 16 位 UTF-16 代码点。将 achar转换为 abyte会导致字符的低字节,但Douglasdan04都是错误的,因为它总是会悄悄地丢弃高字节。如果高字节不为零,则结果取决于是否设置了编译器选项检查算术上溢/下溢

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
于 2017-06-17T17:03:53.780 回答