Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2022-10

Calculating CRC16?

7 messages · 6 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Bo Berglund

I am working on a handler for IoT data from an electricity meter which communicates via TTL serial at 115200 baud. It only sends data in packets of less than 1 kbytes every 5-10 seconds.

In order to validate the data I need to check the CRC16 checksum at the end and here is where I don't find a good way to do it...
The application will run on Linux so I checked for operating support but found only sksum, which apparently does not do CRC16.

Is there some package or code available somewhere which can calculate the CRC16 value over a byte array of some 1000 bytes?

In a description of the protocol after showing the data structure it adds this:

crc16 = libscrc.ibm(example_data).to_bytes(2, 'big').hex() >> '7945'

Googling libscrc brings me to Python code on GitHub, which I am not really able to use, never programmed Python...
https://github.com/hex-in/libscrc

Anyone able to help with FPC implementation?

Bo Berglund Developer in Sweden
Bo Berglund
to Bo Berglund
Bo Berglund wrote 21 lines
I am working on a handler for IoT data from an electricity meter which communicates via TTL serial at 115200 baud. It only sends data in packets of less than 1 kbytes every 5-10 seconds. In order to validate the data I need to check the CRC16 checksum at the end and here is where I don't find a good way to do it... The application will run on Linux so I checked for operating support but found only sksum, which apparently does not do CRC16. Is there some package or code available somewhere which can calculate the CRC16 value over a byte array of some 1000 bytes? In a description of the protocol after showing the data structure it adds this: crc16 = libscrc.ibm(example_data).to_bytes(2, 'big').hex() >> '7945' Googling libscrc brings me to Python code on GitHub, which I am not really able to use, never programmed Python... https://github.com/hex-in/libscrc Anyone able to help with FPC implementation?

I have found a c++ function that purportedly does CRC16:

unsigned int CRC16(unsigned int crc, unsigned char *buf, int len) {
for (int pos = 0; pos < len; pos++)
{

		crc ^= (unsigned int)buf[pos];    // * XOR byte into least sig. byte of

crc

                                          // * Loop over each bit
        for (int i = 8; i != 0; i--)
        {
            // * If the LSB is set
            if ((crc & 0x0001) != 0)
            {
                // * Shift right and XOR 0xA001
                crc >>= 1;
				crc ^= 0xA001;
			}
            // * Else LSB is not set
            else
                // * Just shift right
                crc >>= 1;
		}
	}
	return crc;

}

Can someone please decode this into pascal?

Bo Berglund Developer in Sweden
Jean SUZINEAU
to Bo Berglund: On Tue, 25 Oct 2022 08:30:19 +0200, Bo Berglund via fpc-pascal I have found a c++…

I couldn't verify the code but it should be  relatively close to your  c++ example. Not sure of the width of int type, I supposed it's 16 bits wide:

function CRC16( crc: Word; buf: PByte; len: Word; Poly:Word=$A001): Word;
var
    pos: Word;
    i: Word;
begin
      for pos:= 0 to len-1
      do
        begin
        crc:= crc xor Word(buf[pos]);    // * XOR byte into least sig. byte of crc
        // * Loop over each bit
        for i:= 8 downto 1
        do
          begin
          // * If the LSB is set
          if ((crc and $0001)  0)
          then
              begin
              // * Shift right and XOR 0xA001
              crc:= crc shr 1;
                 crc:= crc xor Poly;
              end
          // * Else LSB is not set
          else
              // * Just shift right
              crc:= crc shr 1;
          end;
        end;
       Result:= crc;
end;
var
    S: String;
begin
      Readln( S);
      WriteLn( IntToHex( CRC16( 0, PByte(@S[1]), Length(S), $8005), 4));
end.
Giuliano Colla
to Marco Borsari: On Tue, 25 Oct 2022 08:30:19 +0200 http://www.retroarchive.org/swag/CRC/index.html…

Il 25/10/22 09:58, Marco Borsari via fpc-pascal ha scritto:

Show quoted text 7 lines
On Tue, 25 Oct 2022 08:30:19 +0200 Bo Berglund via fpc-pascal wrote: > Is there some package or code available somewhere which can calculate the CRC16 > value over a byte array of some 1000 bytes? http://www.retroarchive.org/swag/CRC/index.html

Maybe you'll find this implementation more efficient:

https://gist.github.com/prof7bit/7fc558626f94bd8a81b7

Giuliano

Do not do to others as you would have them do to you.They might have different tastes.
Fabio Luis Girardi
to Giuliano Colla

To array of bytes, check this:

https://github.com/fluisgirardi/pascalscada_v0/blob/master/src/scada/crc16utils.pas

There are two routines: one to calculate, another to check if crc16 matches.

Em ter., 25 de out. de 2022 às 08:13, Giuliano Colla via fpc-pascal <

Show quoted text 25 lines
escreveu: Il 25/10/22 09:58, Marco Borsari via fpc-pascal ha scritto: > On Tue, 25 Oct 2022 08:30:19 +0200 > Bo Berglund via fpc-pascal wrote: > >> Is there some package or code available somewhere which can calculate the CRC16 >> value over a byte array of some 1000 bytes? > http://www.retroarchive.org/swag/CRC/index.html > Maybe you'll find this implementation more efficient: https://gist.github.com/prof7bit/7fc558626f94bd8a81b7 Giuliano -- Do not do to others as you would have them do to you.They might have different tastes. _______________________________________________ fpc-pascal maillist - https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
The best regards, Fabio Luis Girardi PascalSCADA Project http://sourceforge.net/projects/pascalscada http://www.pascalscada.com