Преобразование строки из CP866 в UTF8
У меня есть база данных (MSSQL), и у нее есть таблица с переводами для названий продуктов. Один из языков русский.
Пример записи в базе данных с использованием универсального кириллического декодера Мне удалось выяснить, что это Прдохранитль, а также что кодировка источника CP866, и мне нужно получить WIndows-1257 или utf-8.,
Как это сделать в C#?
Я пробовал что-то вроде
string line = "¸ą¤®åą Øā«ģ";
Encoding cp866 = Encoding.GetEncoding("CP866");
Encoding w1257 = Encoding.GetEncoding("windows-1257");
byte[] cp866Bytes = cp866.GetBytes(line);
byte[] w1257Bytes = Encoding.Convert(cp866, w1257, cp866Bytes);
var lineFinal = w1257.GetString(w1257Bytes);
Кто-нибудь может мне помочь?
Результат для данного кода ?a?¤Raa -Oa?<g
2 ответа
Оставляя в стороне вопросы о том, как такая строка может оказаться в базе данных, вы можете преобразовать ее следующим образом:
string line = "¸ą¤®åą Øā«ģ";
Encoding w1257 = Encoding.GetEncoding("windows-1257");
Encoding cp866 = Encoding.GetEncoding("CP866");
var lineFinal = cp866.GetString(w1257.GetBytes(line));
Потому что ваша исходная строка использует кодовую страницу 1257, и вам нужен CP866.
Обратите внимание, что эта конкретная строка еще сильно повреждена, это приводит к Предохр нитель
и правильное слово Предохранитель
(поэтому у нас есть место вместо а
по индексу 8). Тем не менее, оригинальная строка также содержит пробел в этой позиции, поэтому этот ущерб не является результатом декодирования (возможно, вы просто неправильно скопировали ее в вопрос).
Ваша проблема в том, что вы делаете это наоборот. line
не показывает кириллицу. Персонажи, на которых вы смотрите Windows-1257
персонажи. Когда вы сохраняете строку как кодировку, вы сопоставляете символы с этой кодировкой, а не интерпретируете их как эту кодировку, то есть это только повредит ее.
Также поймите, что текст в.Net не имеет кодировки (или, в любом случае, кодировка не нужна). String
это просто String
, серия символов Юникод. Кодирование становится уместным только тогда, когда вам это нужно в байтах.
Так как мы знаем, что эти персонажи, когда в Windows-1257
кодировка, будет содержать правильные значения байтов, необходимые для их просмотра в CP866
, но в данный момент они чисто-юникод String
и не Windows-1257
необходимо сначала преобразовать его в windows-1257
байты, а затем интерпретировать эти байты как CP866
,
String line = "¸ą¤®åą Øā«ģ";
Encoding cp866 = Encoding.GetEncoding("CP866");
Encoding w1257 = Encoding.GetEncoding("windows-1257");
Byte[] w1257Bytes = w1257.GetBytes(line);
String lineFinal = cp866.GetString(w1257Bytes);