Проблема с преобразованием.ToInt32 и получение индекса ошибки и длины должны ссылаться на местоположение в строке

#c# #linq #checksum #crc

#c# #linq #контрольная сумма #crc

Вопрос:

Мы хотим получить crc-код из строки. например: строка — это (ff03c1), а код crc — это (3d).

Приведенный ниже код работает корректно, пока строка не станет меньше 186 символов. пример строки:

 20000F38080000D1080020110800190D0000000000000000000000000000000020000F38080000D1080020110800190D000000000000000000000000000000020000F38080000D1080020110800190D000000000000000000000000000
  

Но эта строка не работает (187 символов):

 20000F38080000D1080020110800190D0000000000000000000000000000000020000F38080000D1080020110800190D000000000000000000000000000000020000F38080000D1080020110800190D000000000000000000000000000**0**
  

ошибка:
Индекс и длина должны ссылаться на местоположение в строке.
Имя параметра: длина

 public static string CreateCRCCode(string Value)
{
    return Enumerable.Range(0, Value.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToInt32(Value.Substring(x, 2), 16))
                     .Aggregate((i, i1) => i ^ i1)
                     .ToString("X");
}
  

как мы можем использовать строку длиной более 186 символов?

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

1. Этот код завершится ошибкой для любой строки с нечетной длиной из-за Value.Substring(x, 2) .

Ответ №1:

Основная причина

Настоящая проблема не в символах 186 или 187 , проблема в odd и even , что я пытался сказать, вы получите ту же ошибку и для ввода 200 . Также. Причина в том, что,

  • Учтите, что значение = «200» so, Value.Length = 3 и, следовательно, Enumerable.Range(0, Value.Length) даст вам 0,1,2 .
  • После применения .Where(x => x % 2 == 0) коллекция стала 0,2 .

  • Поэтому при применении подстроки( Value.Substring(x, 2) ) будет выполняться поиск подстроки, начинающейся с индекса 2 и не имеющей длины 2 (на второй итерации), которая не является допустимым индексом. Это вызывает ошибку.

Предлагаемое исправление:

  • Я не понимаю никаких причин для применения Where(x => x % 2 == 0) в данном фрагменте, если это необходимо, пожалуйста, перепроверьте условия и сценарии.
  • Измените Enumerable.Range на основе длины коллекции следующим образом:

     Enumerable.Range(0, Value.Length % 2 == 0 ? Value.Length : Value.Length-1)