Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# unicode字符代码的uint和字符转换_C#_.net_Unicode - Fatal编程技术网

C# unicode字符代码的uint和字符转换

C# unicode字符代码的uint和字符转换,c#,.net,unicode,C#,.net,Unicode,有人能解释一下这段代码到底是怎么回事吗 var letter= 'J'; char c = (char)(0x000000ff & (uint)letter); 我知道这是字符的unicode表示形式,但我不完全理解: (0x000000ff & (uint)letter 0x000000ff和向(uint)投出字母的目的是什么?是否有一种简单的方法可以实现相同的结果 谢谢 更新 好的,看起来大多数人认为这是一个糟糕的例子,我不想包含整个类,但我想我也可以这样做,这样你就可以

有人能解释一下这段代码到底是怎么回事吗

var letter= 'J';
char c = (char)(0x000000ff & (uint)letter);
我知道这是字符的unicode表示形式,但我不完全理解:

(0x000000ff & (uint)letter
0x000000ff和向(uint)投出字母的目的是什么?是否有一种简单的方法可以实现相同的结果

谢谢

更新 好的,看起来大多数人认为这是一个糟糕的例子,我不想包含整个类,但我想我也可以这样做,这样你就可以看到上下文了。发件人:


此代码所做的不是转换为Unicode。如果有什么不同的话,那就是另一种方式:

0x000000ff&
部分基本上丢弃unicode字母的第二个字节,并将其转换为只有一个字节长的字母。或者更准确地说:它只保留最重要的字节,而丢弃所有其他字节-这对于
char
也是一样的,因为它的大小为两个字节

我仍然认为这是没有意义的,因为它会导致误报:实际上使用两个字节的Unicode字母只会丢失其中一个字节,从而变成另一个字母 我会简单地去掉这段代码,在你使用
c
的任何地方使用
name[I]

0x000000ff的目的是什么?将字母转换为(uint)是什么

要从[0..255]范围获取代码为的字符:
char
在内存中占用2个字节

e、 g:


您正在解析HTTP头,对吗?这意味着您不应该使用(任何)unicode编码

HTTP头必须是7位ASCII(与请求数据不同)1。这意味着您应该使用ASCII编码而不是默认编码。因此,在解析请求字节时,必须使用
Encoding.ASCII.GetString
而不是
Encoding.Default.GetString
。希望您没有使用
StreamReader
——这是个坏主意,原因很多,包括(可能)头和请求内容之间的编码不匹配

编辑:

至于在微软源代码中的使用——是的,确实如此。不要试图抄袭那些东西——这是一种黑客行为。请记住,您没有微软工程师拥有的测试套件和质量保证,因此即使它确实有效,您最好不要复制此类黑客

我假设它是这样处理的,因为对原则上应该是“ASCII字符串”或仅仅是
byte[]
的东西使用
string
——因为.NET只支持unicode字符串,这被认为是较小的缺点(事实上,这就是为什么代码明确检查
字符串
不包含任何unicode字符的原因——它清楚地知道头必须是ASCII字符——如果字符串包含任何非ASCII字符,它将显式失败。这只是编写供其他人构建的高性能框架时的常见折衷

脚注:

  • 实际上,RFC(2616)指定US-ASCII作为编码,可能意味着ISO-8859-1。然而,RFC不是一个绑定标准(更像是希望从混乱中恢复秩序:D),并且有大量HTTP/1.0和HTTP/1.1客户端(和服务器)与.NET作者一样,我坚持使用7位ASCII(当然,每个字节的编码字符不是真正的7位)

  • var-letter=“J”
    应该是
    var-letter=“J”
    @xanatos谢谢你的更正,这是一个打字错误。我不会说第二个-unicode每个字符的字节数可以比两个多,也可以比两个少。它只需要最低的字节,不管其他字节是什么样子(或者有多少字节)@Luaan:C#中的字符类型大小为两个字节,因此不可能超过两个字节。是的,但这是在
    char
    级别上-这意味着这些字符实际上将被表示为一个代理对-这更糟-不仅你不会去掉一半的unicode字母,而且你会在事实上,添加没有任何意义的伪ASCII字符。我知道您并不是想说使用这样的字符是个好主意,但它甚至比在输出中更改一些字母更复杂。
    char
    将只有两个字节,但unicode字母可以有多个
    char
    s。HTTP头可以e ISO-8859-1(默认情况下,超文本传输协议(HTTP)消息中的消息头字段参数不能携带ISO-8859-1字符集之外的字符),但要点是相同的:1
    byte
    变为1
    char
    ,值的映射为1:1。@xanatos-Hah,我想知道这是否一直存在(即使是原始的HTTP 1.1 RFC 2616也谈到了“US-ASCII”,这可能意味着ISO-8859-1)。显然,它还允许5987中的UTF-8。在任何情况下,大量客户机都采用ASCII,因此坚持使用7位ASCII仍然是一个好主意(也就是说,每8位零,而不是真正的7位。那将是愚蠢的)。就像不指定字符集一样,它意味着iso-8859-1,而大多数客户端认为它意味着客户端应该猜测编码:D@Luaan但是,如果使用
    ISO-8859-1
    ,它的优点是,值为0-255的字节与值为0-255的
    char
    之间的转换为1:1,因此始终是这样安全。然后你可以用另一个编码器重新解码,而不会丢失信息。@Luaan你是一个伟大的治疗者!:-)非常感谢您简洁的回答。@xanatos是的,这绝对是一个很好的观点。这意味着不会有任何数据在途中丢失。当然,它只适用于.NET对其字符串使用的变体-例如,使用UTF-8意味着通过剥离额外的字节,您将丢失127以上的字符(嗯,会将字符弄乱)在ISO-8859-1和UTF-16中,
    
    
      private static string CheckBadChars(string name, bool isHeaderValue)
        {
            if (name == null || name.Length == 0)
            {
                // emtpy name is invlaid
                if (!isHeaderValue)
                {
                    throw name == null ? 
                        new ArgumentNullException("name") :
                        new ArgumentException(SR.GetString(SR.WebHeaderEmptyStringCall, "name"), "name");
                }
    
                // empty value is OK
                return string.Empty;
            }
    
            if (isHeaderValue)
            {
                // VALUE check
                // Trim spaces from both ends
                name = name.Trim(HttpTrimCharacters);
    
                // First, check for correctly formed multi-line value
                // Second, check for absenece of CTL characters
                int crlf = 0;
                for (int i = 0; i < name.Length; ++i)
                {
                    char c = (char)(0x000000ff & (uint)name[i]);
                    switch (crlf)
                    {
                        case 0:
                            if (c == '\r')
                            {
                                crlf = 1;
                            }
                            else if (c == '\n')
                            {
                                // Technically this is bad HTTP.  But it would be a breaking change to throw here.
                                // Is there an exploit?
                                crlf = 2;
                            }
                            else if (c == 127 || (c < ' ' && c != '\t'))
                            {
                                throw new ArgumentException(SR.GetString(SR.WebHeaderInvalidControlChars), "value");
                            }
    
                            break;
    
                        case 1:
                            if (c == '\n')
                            {
                                crlf = 2;
                                break;
                            }
    
                            throw new ArgumentException(SR.GetString(SR.WebHeaderInvalidCRLFChars), "value");
    
                        case 2:
                            if (c == ' ' || c == '\t')
                            {
                                crlf = 0;
                                break;
                            }
    
                            throw new ArgumentException(SR.GetString(SR.WebHeaderInvalidCRLFChars), "value");
                    }
                }
    
                if (crlf != 0)
                {
                    throw new ArgumentException(SR.GetString(SR.WebHeaderInvalidCRLFChars), "value");
                }
            }
            else
            {
                // NAME check
                // First, check for absence of separators and spaces
                if (name.IndexOfAny(InvalidParamChars) != -1)
                {
                    throw new ArgumentException(SR.GetString(SR.WebHeaderInvalidHeaderChars), "name");
                }
    
                // Second, check for non CTL ASCII-7 characters (32-126)
                if (ContainsNonAsciiChars(name))
                {
                    throw new ArgumentException(SR.GetString(SR.WebHeaderInvalidNonAsciiChars), "name");
                }
            }
    
            return name;
        }
    
    char c = (char)(0x000000ff & (uint)name[i]);
    
    var letter= (char)4200; // ၩ
    char c = (char)(0x000000ff & (uint)letter); // h
    
    // or
    // char c = (char)(0x00ff & (ushort)letter);
    
    // ushort (2-byte unsigned integer) is enough: uint is 4-byte unsigned integer