Страницы

Поиск по вопросам

суббота, 7 марта 2020 г.

Проблема с кодировками. В Encoding.Convert есть баг?

#c_sharp #net #windows #encoding


В общем, на работе стоит русская Windows 7, а дома английский Windows 10, так вот
на работе с кодировками проблем нету, а дома какие-то кракозябры.

Попробовал вот таким способом подобрать нужную кодировку, но не получилось:

        string srcStr = "êàíäèäàò";
        string pattern = "кандидат";
        foreach (var src in Encoding.GetEncodings())
        {
            foreach (var dst in Encoding.GetEncodings())
            {
                var tmp = dst.GetEncoding()
                     .GetString(Encoding.Convert(src.GetEncoding(), dst.GetEncoding(),
                         src.GetEncoding().GetBytes(srcStr)));
                if (tmp== pattern)
                {
                    Console.WriteLine($"{src.CodePage}=>{dst.CodePage}");
                }
            }
        }


Хотя вот этот сайт четко определяет нужную кодировку http://www.online-decoder.com/ru

Однако, когда я пытаюсь воспользоваться явно, то опять получаю кракозябры.

Подскажи, в чем мой косяк? Может быть в настройках Win что-нибудь поменять нужно?

В домашней ОС стоит русская локаль для программ без Unicode.

Вообще на работе вот такая строчка работает:

currentText = Encoding.UTF8.GetString(Encoding.Convert(Encoding.Default, Encoding.UTF8,
Encoding.Default.GetBytes(currentText)));


а вот дома каракули на выходе.



Хм...

А вот если так, то кодировка нормально подбирается:

  string srcStr = "êàíäèäàò";
            string pattern = "кандидат";
            foreach (var src in Encoding.GetEncodings())
            {
                foreach (var dst in Encoding.GetEncodings())
                {
                    var dstBytes = src.GetEncoding().GetBytes(srcStr);
                    var tmp = dst.GetEncoding().GetString(dstBytes);
                    if (tmp == pattern)
                    {
                        Console.WriteLine($"{src.DisplayName}=>{dst.DisplayName}");
                    }
                }
            }


Разве первый вариант не идентичный последнему варианту?
    


Ответы

Ответ 1



Ваши варианты неидентичны. Логика второго понятна: мы из байтов получили неправильную строку, интерпретируя их в неправильной кодировке. Мы получаем эти байты назад, и интерпретируем в правильной кодировке. При этом, понятно, байты не меняются, потому что это по сути одни и те же байты, мы лишь меняем их интерпретацию. А ваш первый вариант меняет байты при помощи Convert, понятно, что он не равносилен второму. Метод Convert работает наоборот: он берёт байты, соответствующие строке в одной кодировке, и превращает их в байты той же строки в другой кодировке. То есть var bytes2 = Encoding.Convert(enc1, enc2, bytes); равносильно var s = enc1.GetString(bytes); var bytes2 = enc2.GetBytes(s); Итого: Convert даёт байты другой кодировки для той же строки, а второй вариант даёт другую строку для тех же байтов.

Комментариев нет:

Отправить комментарий