Wie konfiguriere ich die Berechnung der CRC-Tabelle?
Es gibt viele Beispiele für CRC-Berechnungen. Einfache Implementierungen mit Bitverschiebung und effizienter mit einer vorberechneten Tabelle. Neben dem Polynom gibt es aber auch eine Reihe von Parametern einer CRC, die sich auf die Berechnung auswirken. Diese Parameter können Sie hier auswerten:http: //zorc.breitbandkatze.de/crc.htm
Diese Parameter sind
initial value of CRCreflection of input datareflection of output datandgültiger XOR-Wert für CFür einige "Standard" -CRC-Algorithmen sind diese Parameter gut definiert, z. B. CRC-16 (CCITT). Es gibt jedoch einige Implementierungen, die andere Parameter verwenden.
Meine Implementierung muss mit einem CRC16 mit einem CCITT-Polynom kompatibel sein (x 16 + x 12 + x5 + 1). Die Datenbytes und der endgültige CRC müssen jedoch wiedergegeben werden. Ich habe diese Überlegungen in die Berechnungsmethode implementiert. Das ist aber zeitaufwändig. Für eine optimale Leistung muss es aus der Berechnung entfernt werden.
Wie können die Reflexionsparameter der CRC in der Initialisierungsmethode berechnet werden?
Bearbeiten Wie kann ich die einzelnen Parameter einzeln steuern? Ich würde gerne verstehen, wie dasInit
-Funktion funktioniert tatsächlich und wie alle Parameter implementiert sind.
typedef unsigned char uint8_t;
typedef unsigned short crc;
crc crcTable[256];
#define WIDTH (8 * sizeof(crc))
#define TOPBIT (1 << (WIDTH - 1))
#define POLYNOMIAL 0x1021
template<typename t>
t reflect(t v)
{
t r = 0;
for (int i = 0; i < (8 * sizeof v); ++i)
{
r <<= 1;
r |= v&1;
v >>= 1;
}
return r;
}
void Init()
{
crc remainder;
for (int dividend = 0; dividend < 256; ++dividend)
{
remainder = dividend << (WIDTH - 8);
for (uint8_t bit = 8; bit > 0; --bit)
{
if (remainder & TOPBIT)
remainder = (remainder << 1) ^ POLYNOMIAL;
else
remainder = (remainder << 1);
}
crcTable[dividend] = remainder;
}
}
crc Calculate(const uint8_t *message, int nBytes, crc wOldCRC)
{
uint8_t data;
crc remainder = wOldCRC;
for (int byte = 0; byte < nBytes; ++byte)
{
data = reflect(message[byte]) ^ (remainder >> (WIDTH - 8));
remainder = crcTable[data] ^ (remainder << 8);
}
return reflect(remainder);
}
int main()
{
crc expected = 0x6f91;
uint8_t pattern[] = "123456789";
Init();
crc result = Calculate(pattern, 9, 0xFFFF);
if (result != expected)
{
// this output is not relevant to the question, despite C++ tag
printf("CRC 0x%04x wrong, expected 0x%04x\n", result, expected);
}
}