Проблемы с латиницей при расшифровки FromBase64

177
25 декабря 2020, 23:10

Почему расшифровка не поддерживает латиницу? Пробовал разные методы добавления Encoding не помогло (

public static class BaseHelper
{
 public static void EncryptFile(string filename, string output)
 {
  if (File.Exists(filename))
  {
    string b64 = Convert.ToBase64String(EncodingDef(File.ReadAllText(filename)));
    File.WriteAllText(output, b64);
  }
}
public static void DecryptFile(string filename, string output)
{
   if (File.Exists(filename))
   {
     byte[] bb = Convert.FromBase64String(filename);
     string save = EncodingUtf8(bb);
     File.WriteAllText(output, save);
   }
}
 private static byte[] EncodingDef(string file) => 
 Encoding.Default.GetBytes(file);
 private static string EncodingUtf8(byte[] file) => 
  Encoding.UTF8.GetString(file);
}

Использую так:

string filename = "1.txt";
BaseHelper.EncryptFile(filename, "1_enc.txt");
BaseHelper.DecryptFile("1_enc.txt", "1.dec.txt");

Ошибка следующего вида:

Входные данные не являются действительной строкой Base-64, поскольку содержат символ в кодировке, отличной от Base 64, больше двух символов заполнения или недопустимый символ среди символов заполнения.

Answer 1

Устроили тут ромашку: та кодировка, не та кодировка...

Читаем из файла плоский текст сразу в виде байтов, методом ReadAllBytes. Кодировка при этом значения не имеет.

А вот результат в виде строки base64 записываем в файл с выбранной нами кодировкой. Для экономии вполне подойдёт ASCII - она с гарантией перекрывает base64.

string base64 = Convert.ToBase64String(File.ReadAllBytes(plainTextFileName));
File.WriteAllText(base64FileName, base64, encoding);

Где encoding:

Encoding encoding = Encoding.ASCII; // или любая другая

При чтении строки base64 используем ту же самую кодировку. Гадать не нужно: мы её сами назначили при записи, поэтому она нам известна при чтении.

Раскодированный плоский текст опять записываем в виде байтов. Не нужно ломать голову о выборе кодировки: она будет та же, которая была в исходном файле.

var bytes = Convert.FromBase64String(File.ReadAllText(base64FileName, encoding));
File.WriteAllBytes(plainTextFileName, bytes);
Answer 2

На мой взгляд зашифровка и расшифровка должна проводиться в одной и той же кодировке.

Попробуйте вместо:

string b64 = Convert.ToBase64String(EncodingDef(File.ReadAllText(filename)));

Использовать это:

string b64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(File.ReadAllText(filename)));
Answer 3
  1. Фиксим чтение из файла
  2. Меняем кодировку по умолчанию (которая не обязательно utf-8) на utf-8

Получаем рабочий код

public static class BaseHelper
{
    public static void EncryptFile(string filename, string output)
    {
        if (File.Exists(filename))
        {
            string b64 = Convert.ToBase64String(EncodingDef(File.ReadAllText(filename)));
            File.WriteAllText(output, b64);
        }
    }
    public static void DecryptFile(string filename, string output)
    {
        if (File.Exists(filename))
        {
            byte[] bb = Convert.FromBase64String(File.ReadAllText(filename));           
            string save = EncodingUtf8(bb);
            File.WriteAllText(output, save);
        }
    }
    private static byte[] EncodingDef(string file) => Encoding.UTF8.GetBytes(file);
    private static string EncodingUtf8(byte[] file) => Encoding.UTF8.GetString(file);
}
READ ALSO
редактор текста на картинке WPF

редактор текста на картинке WPF

Нужно реализовать функционал редактирования текста на С# как в графических редакторах, например paintУ пользователя возможность перемещать...

170
SQL. Не работает запрос EXISTS

SQL. Не работает запрос EXISTS

Пытаюсь вставить в свою таблицу данные с использованием EXISTS, однако сервер это условие игнорирует и просто вставляет всем студентам оценки

198
Laravel импорт данных из Excel

Laravel импорт данных из Excel

Вопрос уже не раз задавался в сообществе, но меня интересует детали скорее, чем само решениеИтак, ситуация рядовая: есть таблицы

148