I'm trying to implement a 16-CRC [DNP] using c#, the generator polynomial
is given as
I found a standard solution for 16-crc : [ Source ]
public class Crc16
{
const ushort polynomial = 0xA001;
ushort[] table = new ushort[256];
public ushort ComputeChecksum ( byte[] bytes )
{
ushort crc = 0;
for ( int i = 0; i < bytes.Length; ++i )
{
byte index = ( byte ) ( crc ^ bytes[i] );
crc = ( ushort ) ( ( crc >> 8 ) ^ table[index] );
}
return crc;
}
public byte[] ComputeChecksumBytes ( byte[] bytes )
{
ushort crc = ComputeChecksum ( bytes );
return BitConverter.GetBytes ( crc );
}
public Crc16 ()
{
ushort value;
ushort temp;
for ( ushort i = 0; i < table.Length; ++i )
{
value = 0;
temp = i;
for ( byte j = 0; j < 8; ++j )
{
if ( ( ( value ^ temp ) & 0x0001 ) != 0 )
{
value = ( ushort ) ( ( value >> 1 ) ^ polynomial );
}
else
{
value >>= 1;
}
temp >>= 1;
}
table[i] = value;
}
}
}
Now, If I convert my polynomial I get 1 0011 1101 0110 0111
=> (3D65)h
& my question is what do I need to change to work the above solution for the given polynomial.
Edit
: I also need to consider two things,
1) The initial value will be 0 &
2) The final CRC has to be complemented.
Finally, I ended up using the following solution & thought it's worth sharing & it may be useful for someone.
private static int GetCrc ( string BitString )
{
bool[] Res = new bool[17];
bool[] CRC = new bool[16];
int i;
bool DoInvert = false;
string crcBits = string.Empty;
for ( i = 0; i < 16; ++i ) // Init before calculation
CRC[i] = false;
for ( i = 0; i < BitString.Length; ++i )
{
DoInvert = ('1' == BitString[i]) ^ CRC[15]; // XOR required?
CRC[15] = CRC[14];
CRC[14] = CRC[13];
CRC[13] = CRC[12] ^ DoInvert;
CRC[12] = CRC[11] ^ DoInvert;
CRC[11] = CRC[10] ^ DoInvert;
CRC[10] = CRC[9] ^ DoInvert;
CRC[9] = CRC[8];
CRC[8] = CRC[7] ^ DoInvert;
CRC[7] = CRC[6];
CRC[6] = CRC[5] ^ DoInvert;
CRC[5] = CRC[4] ^ DoInvert;
CRC[4] = CRC[3];
CRC[3] = CRC[2];
CRC[2] = CRC[1] ^ DoInvert;
CRC[1] = CRC[0];
CRC[0] = DoInvert;
}
for ( i = 0; i < 16; ++i )
Res[15 - i] = CRC[i] ? true : false;
Res[16] = false;
// The final result must be Complemented
for ( i = 0; i < 16; i++ )
{
if ( Res[i] )
crcBits += "0";
else
crcBits += "1";
}
return Convert.ToInt32 ( crcBits, 2 );
}
The above C# solution is converted from C based auto generated code
from here.