在写入文件时,为什么UTF8编码更改/损坏字节与Base64和ASCII相反?

时间:2017-01-08 14:38:19

标签: c# encoding utf-8

我正在编写一个应用程序,它将接收加密的字节数组,包括文件名和文件字节,使用以下协议:file_name_and_extension|bytes。然后解密字节数组并传入Encoding.UTF8.getString(decrypted_bytes)将是更可取的,因为我想从接收的字节中修剪file_name_and_extension以将实际文件字节保存到file_name_and_extension

我简化了我的应用程序,只接收文件bytes,然后将其传递到Encoding.UTF8.GetString()并返回到带有Encoding.UTF8.getBytes()的字节数组中。之后,我正在尝试编写一个zip文件,但该文件无效。它在使用ASCIIBase64时有效。

private void Decryption(byte[] encryptedMessage, byte[] iv)
{
    using (Aes aes = new AesCryptoServiceProvider())
    {
        aes.Key = receiversKey;
        aes.IV = iv;
        // Decrypt the message
        using (MemoryStream decryptedBytes = new MemoryStream())
        {
            using (CryptoStream cs = new CryptoStream(decryptedBytes, aes.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(encryptedMessage, 0, encryptedMessage.Length);
                cs.Close();

                string decryptedBytesString = Encoding.UTF8.GetString(decryptedBytes.ToArray()); //corrupts the zip
                //string decryptedBytesString = Encoding.ASCII.GetString(decryptedBytes.ToArray()); //works
                //String decryptedBytesString = Convert.ToBase64String(decryptedBytes.ToArray()); //works

                byte[] fileBytes = Encoding.UTF8.GetBytes(decryptedBytesString);
                //byte[] fileBytes = Encoding.ASCII.GetBytes(decryptedBytesString);
                //byte[] fileBytes = Convert.FromBase64String(decryptedBytesString);
                File.WriteAllBytes("RECEIVED\\received.zip", fileBytes);

            }
        }
    }
}

1 个答案:

答案 0 :(得分:3)

因为不应该尝试将原始字节解释为某些编码中的符号,除非他实际知道/可以推断出所使用的编码。

如果您收到一些非特定的原始字节,那么process them as raw bytes

但为什么它有效/不起作用?

由于:

  1. Encoding.Ascii似乎忽略大于127的值并按原样返回它们。所以无论编码/解码完成,原始字节都是一样的。
  2. Base64是一种简单的编码,不会以任何方式更改原始数据。
  3. UTF8 - 从理论上讲,这些字节不是正确的UTF8字符串,我们可能会有一些转换数据丢失(尽管它更可能导致异常)。但最可能的原因是Encoding.UTF8.GetString调用BOM being added Encoding.UTF8.GetBytes 172.16.205.5 domain\administrator 1482857637 Tue Dec 27 19:53:57 2016 172.16.200.237 domain\admin 1482857408 Tue Dec 27 19:50:08 2016 172.16.200.254 domain\cppm 1482857802 Tue Dec 27 19:56:42 2016 172.16.200.200 domain\admin 1482857830 Tue Dec 27 19:57:10 2016 C:\Users\Administrator> Get -ADuser -Identity 1482857637 GivenName: nthere SamAccountName: 1482857637 之后{{1}}。
  4. 无论如何,我再说一遍 - 除非实际是字符串数据/所需格式,否则不要编码/解码任何内容。