We want get crc code from a string. for example: string is (ff03c1) and crc code is (3d).
The bellow code works correctly until the string is less than 186 characters. sample string:
20000F38080000D1080020110800190D0000000000000000000000000000000020000F38080000D1080020110800190D000000000000000000000000000000020000F38080000D1080020110800190D000000000000000000000000000
But this string not working (187 characters):
20000F38080000D1080020110800190D0000000000000000000000000000000020000F38080000D1080020110800190D000000000000000000000000000000020000F38080000D1080020110800190D000000000000000000000000000**0**
error: Index and length must refer to a location within the string. Parameter name: length
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");
}
how we can use string more than 186 character?
Root cause
The real problem is not with the 186
or 187
characters, the problem is the odd
and even
, what I tried to say is, you will get the same error for an input of 200
as well. The reason is that,
Value.Length = 3
and hence Enumerable.Range(0, Value.Length)
will gives you 0,1,2
.After applying .Where(x => x % 2 == 0)
the collection became 0,2
.
So when applying the substring(Value.Substring(x, 2)
) it will search for the substring starts at index 2
and off length 2
(in the second iteration) which is not a valid index. That causes the error.
Proposed Fix:
Where(x => x % 2 == 0)
in the given snippet, if it is necessary please cross check the conditions and scenarios.Change the Enumerable.Range
based on the collection length like the following:
Enumerable.Range(0, Value.Length % 2 == 0 ? Value.Length : Value.Length-1)