Calling C++ method from C# to calculate CRC - c#

I have a C# server which needs to calculate a CRC (CRC16 – CCITT (xModem)) from a byte array. The thing is that I would like to make a call for a C++ code from C#, for performance gain. But I'm struggling to accomplish this task, as the provided C++ algorithm they gave me is apparently not compatible with VC++.
CRC calculation function:
const UINT16 crc_table[16] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
};
UINT16 CalculateCrc( UINT8 *data, UINT32 len )
{
UINT i;
UINT16 crc = 0;
while( len-- )
{
i = ( crc >> 12 ) ^ ( *data >> 4 );
crc = crc_table[ i & 0x0F ] ^ ( crc << 4 );
i = ( crc >> 12 ) ^ ( *data >> 0 );
crc = crc_table[ i & 0x0F ] ^ ( crc << 4 );
data++;
}
return ( crc & 0xFFFF );
}
where *data is a pointer to a byte[] and len is the length of this byte[];
To be able to "inject" this code onto my C# code I created a C++ Class Library,
but I'm uncertain on how to use it after it's finished.
Finally, my questions are:
How to port the provided algorithm to work with VC++?
How to use the compiled Class Library to actually calculate the code on my C#
server?
Is this approach (create a C++ code to calculate the CRC)
better performance wise?

The Just In Time compiler in CLR is pretty good. I don't think you'll see much of a performance gain by using C++. In fact, it may even be slower because of the extra overhead.
Translating your algorithm from C to C# should be pretty easy; just change the data types to their equivalents and add casts where needed:
ushort[] crc_table = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef
};
ushort CalculateCrc( byte[] data )
{
int i;
ushort crc = 0;
int len = data.Length;
for (int j = 0; j < len; j++)
{
i = ( crc >> 12 ) ^ ( data[j] >> 4 );
crc = (ushort) (crc_table[ i & 0x0F ] ^ ( crc << 4 ));
i = ( crc >> 12 ) ^ ( data[j] >> 0 );
crc = (ushort) (crc_table[ i & 0x0F ] ^ ( crc << 4 ));
}
return crc;
}
I haven't tested this, though.

Related

CRC-16/Modbus Implementation in C# malfunction

I'm currently setting up the communication between a controller for a step motor and a computer, coding an application in C# (it is the first time I use this programming language, and although I'm not a computer scientist but an industrial engineer, reason why I'm sure there are some ways of optimizing the function which I don't know, any recommendation on that matter would also be very appreciated). Therefore, I've been using the RS-485 that the controller has to communicate with it, and I've implemented an algorithm that generates the CRC(Cyclic Redundancy Check) bytes required.
And there is where my problem begins. I can't find the reason why my function doesn't generate the correct CRC value. I have checked with some online calculators of CRC and I've also used the example that appears in the Modbus Guide (where it also explains how is the code implemented).
Here is the code I've written for the calculus of the CRC:
class Program
{
static void Main(string[] args)
{
// 0x05, 0x06, 0x17, 0x70, 0x00, 0x01
byte[] prueba = new byte[] { 0x02, 0x07 };
byte[] result = Aux.CRC(prueba);
Console.WriteLine(result[0] + " " + result[1]);
}
}
class Aux{
public static byte[] CRC(byte[] to_evaluate)
{
byte[] CRC_Byte = new byte[2] { 0, 0 };
UInt16 CRC_Register = 0xFFFF; //16 bits 1111.1111.1111.1111
UInt16 CRC_pol = 0xa001; //16 bits 1010.0000.0000.0001
foreach (UInt16 byte_val in to_evaluate)
{
CRC_Register ^= byte_val;
Console.WriteLine("XOR inicial : {0:X}", CRC_Register);
for (byte i = 0; i < 8; i++)
{
CRC_Register >>= 1;
Console.WriteLine("Desplazamiento " + (i + 1) + ": {0:X}", CRC_Register);
if ((CRC_Register & 1) != 0)
{
CRC_Register ^= CRC_pol;
Console.WriteLine("XOR: {0:X}", CRC_Register);
}
}
}
Console.WriteLine("{0:X}",CRC_Register);
byte low_byte_CRC = (byte)((CRC_Register << 8) >> 8);
byte high_byte_CRC = (byte)(CRC_Register >> 8);
CRC_Byte[0] = low_byte_CRC;
CRC_Byte[1] = high_byte_CRC;
return CRC_Byte;
}
}
The expected result using the test array attached and the polinomial 0xa001 is 0x1241 for CRC_Register, and {0x41,0x12} for the CRC_Byte.
I had to implement a CRC check for PPP once in C# and it was absolutely no fun!
I found in this link the code that should correctly generate the CRC. It follows the CRC Generation procedure from section 6.2.2 on page 39 of the document you shared the link to.
// Compute the MODBUS RTU CRC
UInt16 ModRTU_CRC(byte[] buf, int len)
{
UInt16 crc = 0xFFFF;
for (int pos = 0; pos < len; pos++)
{
crc ^= (UInt16)buf[pos]; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--) // Loop over each bit
{
if ((crc & 0x0001) != 0) // If the LSB is set
{
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else // Else LSB is not set
{
crc >>= 1; // Just shift right
}
}
}
// Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
return crc;
}

Store multiple chars in a long and recover them

The following code is used to compact multiple values in a long. The long is used as a key in a C++ unordered_map. It allows me to use the map with a number instead of a complex structure and ifs on each properties. The map searching to be as efficient as possible.
DWORD tmpNo = object->room->details->No;
unsigned char compactNo = tmpNo ;
unsigned __int16 smallX = object->x;
unsigned __int16 smallY = object->y;
unsigned __int64 longCode = 0;
longCode = (item->code[0] << 56) |
(item->code[1] << 48) |
(item->code[2] << 40) |
(compactNo << 32) |
(smallX << 24) |
(smallY << 8);
Am I using the | operator correctly here ?
To recover the values, I tryed :
unsigned char c0 = key >> 56;
unsigned char c1 = key >> 48;
unsigned char c2 = key >> 40;
etc, but it didn't work.
Is it because the original item->code chars are chars and not unsigned chars (the values are always positive though) ?
Also, in an ideal world, the long's values would be recovered in a .NET DLL. Is it possible to do so in C# ?
C# has a byte type for an 8-bit value, but otherwise the logic is similar.
Your | logic looks fine (except you should be shifting smallX by 16 and smallY by 0)
It would help if you gave a complete example.
But assuming that item->code[0] is a char or int (signed or unsigned), you need to convert it to a 64 bit type before shifting, otherwise you end up with undefined behaviour, and the wrong answer.
Something like
((unsigned __int64) item->code[0]) << 56
should work better.
I think that stdint.h is very useful to understand this kind of implementation (sized integers are very meaningful). So here's the code:
#include <stdio.h>
#include <stdint.h>
int8_t getValue8(int index, uint64_t container) {
return (uint8_t)((container >> (index * 8)) & 0XFF);
}
void setValue8(int index, uint64_t* container, uint8_t value) {
// get left part of container including the last byte (cleared by ~0xFF mask) to be used by value
int shift = index * 8;
uint64_t mask = (uint64_t) ~0xFF;
uint64_t left = (*container >> shift) & mask;
left = (left | value) << shift;
// right part of container (complement)
mask = ((uint64_t)1 << ++shift) - 1;
uint64_t right = *container & mask;
// update container
*container = left | right;
}
int main() {
uint64_t* container; // container: can contain 8 chars (64-bit sized container)
uint64_t containerValue = 0;
int n = 8; // n value must be <= 8 considering a 64-bit sized container
uint8_t chars[n]; // eight char values to be stored
// add/set values to container
container = &containerValue;
int i;
for (i = 0; i < n; ++i) {
chars[i] = (uint8_t)((i+1)*10);
setValue8(i, container, chars[i]);
printf("setValue8(%d, container, %d)\n", i, chars[i]);
}
// get values from container
for (i = 0; i < n; ++i) {
printf("getValue8(%d, container)=%d\n", i, getValue8(i, *container));
}
return 0;
}
The code use only bit masks and some bitwise operations, and so you can easily port it to C#. If you have any questions about it just ask. I hope I have been helpful.

Converting Ada code to C#

So I need help converting this ada code int c#, it's basically a checksum algorithm.
ADA:
CHECKSUM_VALUE := ((ROTATE_LEFT_1_BIT(CHECKSUM_VALUE)) xor (CURRENT_VALUE));
This is what I could come up with:
C#:
checksum = RotateLeft(checksum, rotateCount, sizeof(ushort) * 8) ^ word;
RotateLeft Function:
public static int RotateLeft(int value, ushort rotateCount, int dataSize)
{
return (value << rotateCount) | (value >> (dataSize - rotateCount));
}
However when comparing the checksum results from the ada and C# algorithms, they do not match so I think my conversion isn't correct, anyone who has used ada before can give some input would be really helpful.
Thanks
The issue seems to be with the C# and perhaps not with your interpretation of the ADA code. If you are truly rotating a 16 bit unsigned number as your post is implying, then you will need to mask the upper 2 bytes of the resulting integer value so that they do not contribute to the answer. Casting an uint x to ushort in C# will do the equivalent of x & 0x0000FFFF
public static ushort RotateLeft(ushort value, int count)
{
int left = value << count;
int right = value >> (16 - count);
return (ushort)(left | right);
}
This answer is in C, since I don’t have a C# compiler.
You have value as an int, which is signed, so that a right shift extends the sign bit into the vacated space; so in (value << rotateCount) | (value >> (dataSize - rotateCount)), the right-hand half ((value >> (dataSize - rotateCount))) needs to have the top bits masked off. And I don’t know why you need dataSize, isn’t it sizeof(value)?
I think a better solution would be to use unsigned, so that a right shift introduces zeros into the vacated space.
#include <stdio.h>
unsigned rotateLeft(unsigned value, int by) {
const unsigned bits = sizeof(value) * 8;
return (value << by) | (value >> (bits - by));
}
int main() {
unsigned input = 0x52525252;
unsigned result = input;
printf("input: %x\n", input);
{
int j;
for (j = 0; j < 8; j++) {
result = rotateLeft(result, 1);
printf("result: %x\n", result);
}
}
return 0;
}
The output is
input: 52525252
result: a4a4a4a4
result: 49494949
result: 92929292
result: 25252525
result: 4a4a4a4a
result: 94949494
result: 29292929
result: 52525252

C# CRC implementation

I am trying to integrate a Serial-port device into my application, which needs CRC-CCTT validation for the bytes that I send to it.
I'm kinda new into managing byte packets, and need help for this.
It uses this formula for making the CRC calculus:
[CRC-CCITT P(X)= X16 + C12 + C8 + 1]
So for example for the packet: 0xFC 0x05 0x11, the CRC is 0x5627.
Then I send this packet to the device: 0xFC 0x05 0x11 0x27 0x56
Also, packet lenghts will vary from 5 to 255 (including CRC checks bytes)
I don't know how to implement this, so any idea/suggestions will be welcome.
Hope I made myself clear,
Thanks in Advance.
EDIT:
here is the specification of what I need to do:
standard crc-ccitt is x16 + x12 + x5 + 1 I wrote the one # http://www.sanity-free.com/133/crc_16_ccitt_in_csharp.html If I have time I'll see if I can't modify it to run with the x16 + x12 + x8 + 1 poly.
EDIT:
here you go:
public class Crc16CcittKermit {
private static ushort[] table = {
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
0x1081, 0x0108, 0x3393, 0x221A, 0x56A5, 0x472C, 0x75B7, 0x643E,
0x9CC9, 0x8D40, 0xBFDB, 0xAE52, 0xDAED, 0xCB64, 0xF9FF, 0xE876,
0x2102, 0x308B, 0x0210, 0x1399, 0x6726, 0x76AF, 0x4434, 0x55BD,
0xAD4A, 0xBCC3, 0x8E58, 0x9FD1, 0xEB6E, 0xFAE7, 0xC87C, 0xD9F5,
0x3183, 0x200A, 0x1291, 0x0318, 0x77A7, 0x662E, 0x54B5, 0x453C,
0xBDCB, 0xAC42, 0x9ED9, 0x8F50, 0xFBEF, 0xEA66, 0xD8FD, 0xC974,
0x4204, 0x538D, 0x6116, 0x709F, 0x0420, 0x15A9, 0x2732, 0x36BB,
0xCE4C, 0xDFC5, 0xED5E, 0xFCD7, 0x8868, 0x99E1, 0xAB7A, 0xBAF3,
0x5285, 0x430C, 0x7197, 0x601E, 0x14A1, 0x0528, 0x37B3, 0x263A,
0xDECD, 0xCF44, 0xFDDF, 0xEC56, 0x98E9, 0x8960, 0xBBFB, 0xAA72,
0x6306, 0x728F, 0x4014, 0x519D, 0x2522, 0x34AB, 0x0630, 0x17B9,
0xEF4E, 0xFEC7, 0xCC5C, 0xDDD5, 0xA96A, 0xB8E3, 0x8A78, 0x9BF1,
0x7387, 0x620E, 0x5095, 0x411C, 0x35A3, 0x242A, 0x16B1, 0x0738,
0xFFCF, 0xEE46, 0xDCDD, 0xCD54, 0xB9EB, 0xA862, 0x9AF9, 0x8B70,
0x8408, 0x9581, 0xA71A, 0xB693, 0xC22C, 0xD3A5, 0xE13E, 0xF0B7,
0x0840, 0x19C9, 0x2B52, 0x3ADB, 0x4E64, 0x5FED, 0x6D76, 0x7CFF,
0x9489, 0x8500, 0xB79B, 0xA612, 0xD2AD, 0xC324, 0xF1BF, 0xE036,
0x18C1, 0x0948, 0x3BD3, 0x2A5A, 0x5EE5, 0x4F6C, 0x7DF7, 0x6C7E,
0xA50A, 0xB483, 0x8618, 0x9791, 0xE32E, 0xF2A7, 0xC03C, 0xD1B5,
0x2942, 0x38CB, 0x0A50, 0x1BD9, 0x6F66, 0x7EEF, 0x4C74, 0x5DFD,
0xB58B, 0xA402, 0x9699, 0x8710, 0xF3AF, 0xE226, 0xD0BD, 0xC134,
0x39C3, 0x284A, 0x1AD1, 0x0B58, 0x7FE7, 0x6E6E, 0x5CF5, 0x4D7C,
0xC60C, 0xD785, 0xE51E, 0xF497, 0x8028, 0x91A1, 0xA33A, 0xB2B3,
0x4A44, 0x5BCD, 0x6956, 0x78DF, 0x0C60, 0x1DE9, 0x2F72, 0x3EFB,
0xD68D, 0xC704, 0xF59F, 0xE416, 0x90A9, 0x8120, 0xB3BB, 0xA232,
0x5AC5, 0x4B4C, 0x79D7, 0x685E, 0x1CE1, 0x0D68, 0x3FF3, 0x2E7A,
0xE70E, 0xF687, 0xC41C, 0xD595, 0xA12A, 0xB0A3, 0x8238, 0x93B1,
0x6B46, 0x7ACF, 0x4854, 0x59DD, 0x2D62, 0x3CEB, 0x0E70, 0x1FF9,
0xF78F, 0xE606, 0xD49D, 0xC514, 0xB1AB, 0xA022, 0x92B9, 0x8330,
0x7BC7, 0x6A4E, 0x58D5, 0x495C, 0x3DE3, 0x2C6A, 0x1EF1, 0x0F78
};
public static ushort ComputeChecksum( params byte[] buffer ) {
if ( buffer == null ) throw new ArgumentNullException( );
ushort crc = 0;
for ( int i = 0; i < buffer.Length; ++i ) {
crc = (ushort)( ( crc >> 8 ) ^ table[( crc ^ buffer[i] ) & 0xff] );
}
return crc;
}
public static byte[] ComputeChecksumBytes( params byte[] buffer ) {
return BitConverter.GetBytes( ComputeChecksum( buffer ) );
}
}
sample:
ushort crc = Crc16CcittKermit.ComputeChecksum( 0xFC, 0x05, 0x11 );
byte[] crcBuffer = Crc16CcittKermit.ComputeChecksumBytes( 0xFC, 0x05, 0x11 )
// crc = 0x5627
// crcBuffer = { 0x27, 0x56 }
Have you tried Googling for an example? There are many of them.
Example 1: http://tomkaminski.com/crc32-hashalgorithm-c-net
Example 2: http://www.sanity-free.com/12/crc32_implementation_in_csharp.html
You also have native MD5 support in .Net through System.Security.Cryptography.MD5CryptoServiceProvider.
EDIT:
If you are looking for an 8-bit algorithm: http://www.codeproject.com/KB/cs/csRedundancyChckAlgorithm.aspx
And 16-bit: http://www.sanity-free.com/133/crc_16_ccitt_in_csharp.html
LOL, I've encountered exactly the same STATUS REQUEST sequense, i'm currently developing software to use with CashCode Bill Validator:). Here's the code worked for me, it's CRC16-CCITT with reversed polynomial equals 0x8408 (BDPConstants.Polynomial in the code). That's the code worked for me:
// TableCRC16Size is 256 of course, don't forget to set in somewhere
protected ushort[] TableCRC16 = new ushort[BDPConstants.TableCRC16Size];
protected void InitCRC16Table()
{
for (ushort i = 0; i < BDPConstants.TableCRC16Size; ++i)
{
ushort CRC = 0;
ushort c = i;
for (int j = 0; j < 8; ++j)
{
if (((CRC ^ c) & 0x0001) > 0)
CRC = (ushort)((CRC >> 1) ^ BDPConstants.Polynominal);
else
CRC = (ushort)(CRC >> 1);
c = (ushort)(c >> 1);
}
TableCRC16[i] = CRC;
}
}
protected ushort CalcCRC16(byte[] aData)
{
ushort CRC = 0;
for (int i = 0; i < aData.Length; ++i)
CRC = (ushort)(TableCRC16[(CRC ^ aData[i]) & 0xFF] ^ (CRC >> 8));
return CRC;
}
Initialize the table somewhere (e.g. Form constructor):
InitCRC16Table();
then use it in your code just like that,
You can use List of bytes instead of array, more convinient to pack byte data in the 'packet' for sending
uint CRC = CalcCRC16(byte[] aByte)
// You need to split your CRC in two bytes of course
byte CRCHW = (byte)((CRC) / 256); // that's your 0x56
byte CRCLW = (byte)(CRC); // that's your 0x27
it works and dose not need table:
/// <summary>
/// Gens the CRC16.
/// CRC-1021 = X(16)+x(12)+x(5)+1
/// </summary>
/// <param name="c">The c.</param>
/// <param name="nByte">The n byte.</param>
/// <returns>System.Byte[][].</returns>
public ushort GenCrc16(byte[] c, int nByte)
{
ushort Polynominal = 0x1021;
ushort InitValue = 0x0;
ushort i, j, index = 0;
ushort CRC = InitValue;
ushort Remainder, tmp, short_c;
for (i = 0; i < nByte; i++)
{
short_c = (ushort)(0x00ff & (ushort) c[index]);
tmp = (ushort)((CRC >> 8) ^ short_c);
Remainder = (ushort)(tmp << 8);
for (j = 0; j < 8; j++)
{
if ((Remainder & 0x8000) != 0)
{
Remainder = (ushort)((Remainder << 1) ^ Polynominal);
}
else
{
Remainder = (ushort)(Remainder << 1);
}
}
CRC = (ushort)((CRC << 8) ^ Remainder);
index++;
}
return CRC;
}
You are actually using CRC-XMODEM LSB-reverse (with 0x8408 coefficient). C# code for this calculus is:
public void crc_bytes(int[] int_input)
{
int_array = int_input;
int int_crc = 0x0; // or 0xFFFF;
int int_lsb;
for (int int_i = 0; int_i < int_array.Length; int_i++)
{
int_crc = int_crc ^ int_array[int_i];
for (int int_j = 0; int_j < 8; int_j ++ )
{
int_lsb = int_crc & 0x0001; // Mask of LSB
int_crc = int_crc >> 1;
int_crc = int_crc & 0x7FFF;
if (int_lsb == 1)
int_crc = int_crc ^ 0x8408;
}
}
int_crc_byte_a = int_crc & 0x00FF;
int_crc_byte_b = (int_crc >> 8) & 0x00FF;
}
Read more (or download project):
http://www.cirvirlab.com/index.php/c-sharp-code-examples/141-c-sharp-crc-computation.html

Convert CRC-CCITT Kermit 16 DELPHI code to C#

I am working on a function that will give me a Kermit CRC value from a HEX string. I have a piece of code in DELPHI. I am a .NET developer and need the code in C#.
function CRC_16(cadena : string):word;
var
valuehex : word;
i: integer;
CRC : word;
Begin
CRC := 0;
for i := 1 to length(cadena) do
begin
valuehex := ((ord(cadena[i]) XOR CRC) AND $0F) * $1081;
CRC := CRC SHR 4;
CRC := CRC XOR valuehex;
valuehex := (((ord(cadena[i]) SHR 4) XOR LO(CRC)) AND $0F);
CRC := CRC SHR 4;
CRC := CRC XOR (valuehex * $1081);
end;
CRC_16 := (LO(CRC) SHL 8) OR HI(CRC);
end;
I got the code from this webpage: Kermit CRC in DELPHI
I guess that Delphi function is correct. If any one can please convert the code to C# that will be great. I tried to convert to C#, but got lost in WORD data type and the LO function of Delphi. Thank you all.
From MSDN forums:
static long ComputeCRC(byte[] val)
{
long crc;
long q;
byte c;
crc = 0;
for (int i = 0; i < val.Length; i++)
{
c = val[i];
q = (crc ^ c) & 0x0f;
crc = (crc >> 4) ^ (q * 0x1081);
q = (crc ^ (c >> 4)) & 0xf;
crc = (crc >> 4) ^ (q * 0x1081);
}
return (byte)crc << 8 | (byte)(crc >> 8);
}
Use Encoding.ASCII.GetBytes(string) to convert a string to a byte[].
A word is a 16-bit unsigned integer (which can store the values 0..65535).
Lo returns the low-order byte of an integer. So if the integer is 0x7B41AF, for example, lo will return 0xAF.

Categories