Проблема с преобразованием hex в ascii в C#

#c# #ascii #overflow #hex

#c# #ascii #переполнение #hex

Вопрос:

Из-за проблем с приведенным ниже кодом я получаю эту ошибку…

значение было либо слишком большим, либо слишком маленьким для символа… в строке

sb.Append(Преобразовать.ToChar (Преобразовать.ToUint32(hs, 16)));

         for (int i = 0; i < hexString.Length - 1; i  = 2)
        {
            String hs = hexString.Substring(i, i   2);

            sb.Append(Convert.ToChar(Convert.ToUInt32(hs, 16)));

        }
  

Есть какие-нибудь советы для новичков в C #?

спасибо 🙂

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

1. Поскольку я не тестирую ваш код, чтобы узнать, есть ли какие-либо другие проблемы, я не буду публиковать это в качестве ответа. Если это окажется единственной проблемой, любой из других отвечающих здесь может украсть ее и включить в свой. Обратите внимание, что вторым параметром для Substring является не индекс, на котором нужно остановиться, а длина, поэтому с каждой итерацией вы набираете все более длинные строки. Вместо этого вы должны просто передать 2 .

Ответ №1:

Похоже, что ваша шестнадцатеричная подстрока при преобразовании в UInt32-битную базовую 16 (hex) слишком велика (выходит за рамки) используемого вами набора символов.

Проверьте ваше преобразование в Uint32 и убедитесь, что его действительно можно преобразовать в char, то есть оно допустимо.

Ответ №2:

Редактировать

Как указывает @Lasse, Substring принимает начальный индекс и длину, но похоже, что вы пытаетесь передать ему начальный индекс и конечный индекс, поскольку вы передаете i 2 каждому вызову. Это означает, что первая итерация создаст двухсимвольную подстроку, вторая будет трехсимвольной подстрокой и так далее. Просто перейдите 2 к нему:

 String hs = hexString.Substring(i, 2);
  

Это должно исправить реальную проблему.

Хотя это ничего не нарушает, вы должны знать, что то, что вы делаете, не преобразуется в ASCII. ASCII — это особая кодировка символов, которая Convert.ToChar преобразует числовое значение в соответствующий символ Unicode (в частности, UTF-16). Пока ваши значения варьируются только от 0 до 127 ( 00 to 7F в шестнадцатеричном формате), вы подходите для всех практических целей, поскольку форматы Unicode используют символы со стандартным набором символов ASCII. Однако, если ваши символы используют одно из расширений ASCII (например, Latin-1, которое распространено в Windows), то эти символы не будут совпадать.

Если ваши данные в формате ASCII и вам необходимо поддерживать значения больше 127, вы можете преобразовать свою шестнадцатеричную строку в byte[] , а затем передать ее в ASCIIEncoding класс для анализа этих данных в формате ASCII:

 byte[] data = new byte[hexString.Length / 2];

for(int i = 0; i < hexString.Length - 1; i  = 2)
{
    data[i / 2] = byte.Parse(hexString.Substring(i, 2));
}

string output = System.Text.Encoding.ASCII.GetString(data);
  

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

1. Приведите пример символа ASCII, ЛЮБОГО символа, для которого исходный код не работает. Вы не можете, потому что символы от 0 до 127 в Unicode — это весь набор символов ASCII в том же порядке.

2. Даже в UTF-8 от 0 до 127 представлено в виде 1 байта, как и в ASCII.

3. Да, символы в диапазоне ASCII одинаковы; однако код операционной системы способен обрабатывать значения, отличные от ASCII, и то, что он называет «ASCII», может быть одним из расширенных наборов символов ASCII, таких как Latin-1, что не совпадает ни с одним из форматов Unicode. Код, который фактически обрабатывает символы как ASCII, а не удобство четности UTF-ASCII, не более сложен, так почему бы не использовать его?

Ответ №3:

 string assumedASCII = string.Format(@"x{0:x4}", (int)hexString);