I need to calculate a CRC checksum for a CAN BUS.
Scenario:
My input looks always like the following (where x
is either 1
or 0
, *
marks multiple times x
, |
marks a section and -
is a change of input method, lb
is Label
, tb
is TextBox
, cb
is ComboBox
):
lb
: 0tb
: 11xcb
: xcb
: xlb
: 1tb
: 4x =>Convert.ToString(8-64 / 8, 2).PadLeft(4, '0');
tb
: 8-64x, =>8-64 % 8 == 0
tb
: 15x =>CRC of above
lb
: 1lb
: 11lb
: 1111111lb
: 111
Which returns this layout:
0|11*x-x|x-1-4*x|64*x|15*x-1|11|1111111|111
Example:
00101010101000100100101010100101010(missing 15*x CRC sum)1111111111111
This string will be processed by the following string extension, so maximal 5 equal digits follow each other:
public static string Correct4CRC(this string s)
{
return s.Replace("00000", "000001").Replace("11111", "111110");
}
After that following method returns the divisor:
public static BigInteger CreateDivisor(string s)
{
var i = BigInteger.Parse(s);
var d = BigInteger.Pow(i, 15) + BigInteger.Pow(i, 14) + BigInteger.Pow(i, 10) + BigInteger.Pow(i, 8) + BigInteger.Pow(i, 7) + BigInteger.Pow(i, 4) + BigInteger.Pow(i, 3) + 1;
return d;
}
The only problem I've got is the part with ^
:
public static string CRC(this string s)
{
var dd = s.Correct4CRC();
var dr = dd.CreateDivisor().ToString();
int drl = dr.Length;
var d = dd.Substring(0, drl).CreateDivisor();
var f = d ^ dr.CreateDivisor();
var p = true;
while (p)
{
d = dd.Substring(0, drl).CreateDivisor();
f = d ^ dr.CreateDivisor();
p = d > dd.CreateDivisor();
}
return f.ToString();
}
I know this might be closed as asking for code, but please bear with me as I really don't get it. Another problem is, that there is no real documentation which helped me figuring it out.
Anyway, if you know one good doc, which solves my problem please add it as a comment. I'll check it out and close the answer by myself if I get it.
I think your bitstuffing is wrong (the replacement of 00000 with 000001 and of 11111 with 111110), because it doesn't handle avalanche replacements... 0000011110000 that becomes 0000011111000001.
Here http://blog.qartis.com/can-bus/ there seems to be an example. The page is then linked to http://ghsi.de/CRC/index.php?Polynom=1100010110011001&Message=2AA80 that generates some C code for calculating the CRC-15.
and then:
Note that you have to put the value for the ACK slot