Почему Encoding.Default.GetBytes () возвращает разные результаты в VB.NET и C #? - PullRequest
7 голосов
/ 29 мая 2009

Недавно мы натолкнулись на пример кода от поставщика для хэширования секретного ключа для вызова веб-службы, его пример был в VB.NET, который мы преобразовали в C #. Это привело к тому, что хеширование произвело различный ввод. Оказывается, они генерировали ключ для шифрования путем преобразования массива char в строку и обратно в байтовый массив. Это привело меня к открытию, что VB.NET и кодировщик C # по умолчанию работают с некоторыми символами по-разному.

C #:

Console.Write(Encoding.Default.GetBytes(new char[] { (char)149 })[0]);

VB:

Dim b As Char() = {Chr(149)}
Console.WriteLine(Encoding.Default.GetBytes(b)(0))

Выход C # равен 63, а VB - правильное значение байта 149. если вы используете любое другое значение, например 145 и т. д., выходной результат совпадает.

В процессе отладки кодером по умолчанию для VB и C # является SBCSCodePageEncoding.

Кто-нибудь знает, почему это так?

Я исправил пример кода, напрямую инициализировав массив байтов, которым он должен был быть в первую очередь, но я все еще хочу знать, почему кодировщик, который не должен быть специфичным для языка, выглядит именно так. 1015 *

Ответы [ 5 ]

10 голосов
/ 29 мая 2009

Если вы используете ChrW (149), вы получите другой результат - 63, такой же, как C #.

Dim b As Char() = {ChrW(149)}
Console.WriteLine(Encoding.Default.GetBytes(b)(0))

Прочтите документацию , чтобы увидеть разницу - которая объяснит ответ

5 голосов
/ 29 мая 2009

Функция VB Chr принимает аргумент в диапазоне от 0 до 255 и преобразует его в символ с использованием текущей кодовой страницы по умолчанию. Он выдаст исключение, если вы передадите аргумент за пределы этого диапазона.

ChrW примет 16-разрядное значение и вернет соответствующее значение System.Char без использования кодировки - следовательно, даст тот же результат, что и опубликованный вами код C #.

Примерный эквивалент вашего кода VB в C # без использования класса VB Strings (это класс, который содержит Chr и ChrW) будет:

char[] chars = Encoding.Default.GetChars(new byte[] { 149 });
Console.Write(Encoding.Default.GetBytes(chars)[0]);
0 голосов
/ 29 мая 2009

Я полагаю, что эквивалент в VB - ChrW (149).

Итак, этот код VB ...

    Dim c As Char() = New Char() { Chr(149) }
    'Dim c As Char() = New Char() { ChrW(149) }
    Dim b As Byte() = System.Text.Encoding.Default.GetBytes(c)
    Console.WriteLine("{0}", Convert.ToInt32(c(0)))
    Console.WriteLine("{0}", CInt(b(0)))

выдает тот же вывод, что и этот код C # ...

    var c = new char[] { (char)149 };
    var b = System.Text.Encoding.Default.GetBytes(c);
    Console.WriteLine("{0}", (int)c[0]);  
    Console.WriteLine("{0}", (int) b[0]);
0 голосов
/ 29 мая 2009

Различные операционные системы могут использовать разные кодировки по умолчанию. Поэтому данные передаются с одного операционная система для другого может быть переведено неправильно. Чтобы убедиться, что закодированные байты декодируются правильно, ваше приложение должно использовать кодировка Unicode, то есть UTF8Encoding, UnicodeEncoding или UTF32 Кодирование с преамбулой. Другой вариант заключается в использовании протокол более высокого уровня, чтобы гарантировать, что тот же формат используется для кодирования и расшифровка.

от http://msdn.microsoft.com/en-us/library/system.text.encoding.default.aspx

Можете ли вы проверить, что генерирует каждый язык при явном кодировании с использованием utf8?

0 голосов
/ 29 мая 2009

Кодировка по умолчанию зависит от машины и потока, поскольку использует текущую кодовую страницу. Обычно вы должны использовать что-то вроде Encoding.UTF8, чтобы вам не приходилось беспокоиться о том, что происходит, когда одна машина использует Unicode, а другая - 1252-ANSI.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...