/ / Dlaczego kodowanie UTF8 zmienia / uszkadza bajty w przeciwieństwie do Base64 i ASCII, kiedy pisze do pliku? - c #, kodowanie, utf-8

Dlaczego kodowanie UTF8 zmienia / psuje bajty jako przeciwstawiające się Base64 i ASCII podczas zapisu do pliku? - c #, kodowanie, utf-8

Piszę aplikację, która otrzyma zaszyfrowaną tablicę bajtów, składającą się z nazwy pliku i bajtów pliku, z następującym protokołem: file_name_and_extension|bytes. Tablica bajtów jest następnie odszyfrowywana i przekazywana do Encoding.UTF8.getString(decrypted_bytes) byłoby lepiej, ponieważ chciałbym przyciąć file_name_and_extension z odebranych bajtów, aby zapisać rzeczywiste bajty pliku w file_name_and_extension.

Uprościłem aplikację, aby otrzymywać tylko pliki bytes które są następnie przekazywane do Encoding.UTF8.GetString() i z powrotem do tablicy bajtów za pomocą Encoding.UTF8.getBytes(). Następnie próbuję napisać plik zip, ale plik jest nieprawidłowy. Działa podczas używania ASCII lub Base64.

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

}
}
}
}

Odpowiedzi:

3 dla odpowiedzi № 1

Ponieważ nie należy próbować interpretować nieprzetworzonych bajtów jako symboli w niektórych kodowaniach, chyba że tak naprawdę zna / umie wydedukować zastosowane kodowanie.

Jeśli otrzymasz jakieś nieokreślone surowe bajty, to przetwarzaj je jako surowe bajty.

Ale dlaczego to działa / nie działa?

Bo:

  1. Kodowanie: Ascii wydaje się ignorować wartości większe niż 127 i zwraca je takimi, jakie są. Więc bez względu na wykonane kodowanie / dekodowanie, surowe bajty będą takie same.
  2. Base64 to proste kodowanie, które w żaden sposób nie zmienia oryginalnych danych.
  3. UTF8 - teoretycznie z tymi bajtami, które nie są poprawnymi ciągami UTF8, możemy mieć pewną utratę danych konwersji (choć bardziej prawdopodobne jest, że wystąpi wyjątek). Ale najbardziej prawdopodobnym powodem jest BOM jest dodawany podczas Encoding.UTF8.GetString połączenie, które pozostanie tam po Encoding.UTF8.GetBytes.

W każdym razie powtarzam - nie koduj / dekoduj niczego, chyba że jest to właściwie ciąg danych / wymagany format.