0

I'm trying to convert a string to a byte[] using the ASCIIEncoder object in the .NET library. The string will never contain non-ASCII characters, but it will usually have a length greater than 16. My code looks like the following:

public static byte[] Encode(string packet)
{
    ASCIIEncoder enc = new ASCIIEncoder();
    byte[] byteArray = enc.GetBytes(packet);
    return byteArray;
}

By the end of the method, the byte array should be full of packet.Length number of bytes, but Intellisense tells me that all bytes after byteArray[15] are literally questions marks that cannot be observed. I used Wireshark to view byteArray after I sent it and it was received on the other side fine, but the end device did not follow the instructions encoded in byteArray. I'm wondering if this has anything to do with Intellisense not being able to display all elements in byteArray, or if my packet is completely wrong.

4

2 回答 2

2

标准编码器使用替换字符回退策略。如果目标字符集中不存在某个字符,它们会编码一个替换字符(默认为“?”)。

对我来说,这比无声的失败更糟糕;这是数据损坏。我更喜欢图书馆告诉我什么时候我的假设是错误的。

您可以派生一个引发异常的编码器:

Encoding.GetEncoding(
    "us-ascii",
    new EncoderExceptionFallback(), 
    new DecoderExceptionFallback());

如果您真的只使用 Unicode 的 ASCII 范围内的字符,那么您将永远不会看到异常。

于 2014-08-15T04:50:53.633 回答
2

如果您的packet字符串基本上包含 0-255 范围内的字符,那么ASCIIEncoding这不是您应该使用的。ASCII 只定义字符代码 0-127;128-255 范围内的任何内容都会变成问号(如您所见),因为没有在 ASCII 中定义字符。

考虑使用这样的方法将字符串转换为字节数组。(这假设每个字符的序数值在 0-255 范围内,并且序数值是您想要的。)

public static byte[] ToOrdinalByteArray(this string str)
{
    if (str == null) { throw new ArgumentNullException("str"); }

    var bytes = new byte[str.Length];
    for (int i = 0; i < str.Length; ++i) {
        // Wrapping the cast in checked() will trigger an OverflowException
        // if the character being converted is out of range for a byte.
        bytes[i] = checked((byte)str[i]);
    }

    return bytes;
}

Encoding类层次结构是专门为处理文本而设计的。您在这里所拥有的似乎不是文本,因此您应该避免使用这些类。

于 2014-08-14T18:45:20.943 回答