Skip to content

Instantly share code, notes, and snippets.

@zzeroo
Created October 3, 2016 14:18
Show Gist options
  • Save zzeroo/95058de022476063ce6d6e7bae3e4bdd to your computer and use it in GitHub Desktop.
Save zzeroo/95058de022476063ce6d6e7bae3e4bdd to your computer and use it in GitHub Desktop.
CRC-16 Funktion und Aufruf in C
// gcc -o crc16 crc16.c && ./crc16 2 7 # ./crc16 0x2 0x7 # geht auch .oO
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
// CRC-16 Funktion nach dem Vorbild von https://ctlsys.com/how_to_compute_the_modbus_rtu_message_crc/
unsigned short crc16(unsigned char buf[], int len) {
// Start Definition nach Modbus Standard http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf
// Seite 39ff
unsigned short crc = 0xFFFF;
// Durchlaufe jedes Byte (char)
for (int pos = 0; pos < len; pos++) {
// XOR das erste Byte des Buffers mit dem low-order Byte des 16bit CRC
// Registers. Das Ergebnis wird ebenfalls im CRC Register gespeichert
crc ^= (unsigned short)buf[pos];
// Loop über jedes Bit
for (int i = 8; i != 0; i--) {
// Shifte das CRC Register ein Bit nach rechts (Richtung LSB),
// und fülle das MSB mit einer Null auf (Step 3)
if ((crc & 0x001) != 0) {
// (Wenn LSB 1 ist)
crc >>= 1;
// XOR das CRC Register mit dem Polynominal Wert 0xA001 (Step 4)
crc ^= 0xA001;
} else {
// (Wenn LSB Null war) Shifte CRC Register ein bit nach rechts (Step 3)
crc >>= 1;
}
}
}
return crc;
}
int main(int argc, char* argv[]) {
// Wenn keine Parameter übergeben wurden Fehler ausgeben.
if (argc < 2) {
fprintf(stderr, "Usage: %s <NUMBERS>\n", argv[0]);
exit(EXIT_FAILURE);
}
// Message Buffer (Array in der Grösse der übergebenen Parameter,
// -1 da er erste Parameter der Name der Programm ist)
// Wird also ein Parameter übergeben, dann ist das Array 1Byte (char) groß
char message[argc - 1];
// Jeder einzelne "String"-Parameter wird nun in ein Char gekastet
// sie dazu auch `man strtol` der letzte Parameter ist interessant ><
for (int i = 1; i < argc; i++) {
message[i - 1] = (char)strtol(argv[i], NULL, 0);
}
// HIER WIRD DIE CRC16 Funktion nun endlich aufgerufen.
// Parameter sind der message Buffer und dessen Größe
int result = crc16(message, sizeof(message));
// Das Resultat wird nun noch in Hex und Dezimal ausgegeben
printf("crc16 ist: 0x%X (%d)\r\n", result, result);
return (0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment