Calcul Crc 18Bit En C

Calcul CRC 18bit en C

Calculez un CRC 18 bits de manière fiable avec un moteur générique, des paramètres complets et une visualisation du CRC cumulatif par octet. Cet outil convient aux tests, au débogage embarqué, à la validation de trames et à la préparation d’une implémentation en C.

Largeur fixée à 18 bits Entrée ASCII ou hexadécimale Initialisation, XOR final, réflexion
Saisissez un texte ASCII classique ou une suite hexadécimale selon le format choisi.
Vous pouvez entrer une valeur décimale, binaire ou hexadécimale, par exemple 0x102899 ou 0x2899 selon votre convention.

Guide expert du calcul CRC 18bit en C

Le calcul d’un CRC 18 bits en C répond à un besoin très concret : détecter des erreurs de transmission ou de stockage avec une empreinte plus compacte qu’un CRC 32, tout en offrant une robustesse supérieure à un CRC 16 dans certains scénarios. CRC signifie Cyclic Redundancy Check. Il ne s’agit pas d’un algorithme de chiffrement, ni d’un mécanisme d’authentification. Son objectif principal est la détection d’erreurs accidentelles dans un flux binaire, une trame radio, un message série, un paquet réseau spécialisé ou un bloc mémoire.

En pratique, quand on parle de “calcul CRC 18bit en C”, on parle rarement d’une simple formule unique. Un CRC est défini par un ensemble de paramètres : la largeur du registre, le polynôme générateur, la valeur initiale, le XOR final et parfois la réflexion des bits en entrée et en sortie. C’est précisément pour cette raison que deux programmes différents peuvent afficher des résultats contradictoires tout en prétendant calculer un CRC 18 bits. Le problème n’est pas forcément le code, mais souvent la fiche de paramètres.

Le langage C reste le meilleur terrain pour implémenter un CRC lorsqu’on travaille sur du firmware, des microcontrôleurs, des pilotes bas niveau ou des systèmes temps réel. Il permet un contrôle fin sur les types, la mémoire, la taille du registre, l’ordre des bits et les optimisations. Le défi principal avec un CRC 18 bits, c’est que la largeur n’est pas alignée sur les tailles natives les plus courantes comme 8, 16, 32 ou 64 bits. Il faut donc être rigoureux dans le masquage des bits et dans la gestion du bit de poids fort.

Comment fonctionne un CRC 18 bits

Le principe mathématique d’un CRC repose sur une division polynomiale dans l’algèbre binaire. Les additions et soustractions sont remplacées par des XOR. Le message est traité bit par bit ou octet par octet. Le registre de travail est décalé, puis corrigé par XOR avec le polynôme lorsque le bit de tête est positionné. À la fin, le reste obtenu constitue le CRC.

Pour un CRC 18 bits, le registre final comporte exactement 18 bits utiles. Cela signifie qu’il existe 262144 valeurs possibles, soit 218. Si l’on modélise les collisions aléatoires de manière uniforme, la probabilité théorique qu’une erreur aléatoire passe inaperçue est d’environ 1 sur 262144, soit 0,0003815 %. Ce chiffre est une approximation utile pour raisonner sur les erreurs aléatoires, mais la qualité réelle dépend fortement du polynôme et de la structure des erreurs rencontrées.

Les paramètres qu’il faut documenter sans exception

  • Width : ici 18 bits.
  • Polynomial : le polynôme générateur. Selon les outils, il est saisi avec ou sans le bit implicite de degré 18.
  • Init : l’état initial du registre CRC.
  • XorOut : la valeur appliquée au registre final avant publication du résultat.
  • RefIn : indique si chaque octet d’entrée est réfléchi bit à bit.
  • RefOut : indique si le CRC final est réfléchi avant le XOR final.

Un excellent réflexe en C consiste à stocker ces paramètres dans une structure. Cela facilite les tests unitaires, rend le code plus lisible et évite les erreurs de configuration cachées dans plusieurs fonctions.

Pourquoi les implémentations en C se trompent souvent

  1. Le polynôme est fourni avec le bit de degré inclus alors que le code attend uniquement les 18 bits stockés.
  2. Le registre n’est pas masqué après chaque décalage, ce qui laisse des bits hors plage contaminer le calcul.
  3. Le développeur inverse les bits d’entrée mais oublie d’adapter la logique de sortie.
  4. Le flux hexadécimal est lu comme une chaîne ASCII, ce qui modifie complètement les octets traités.
  5. Le test de validation utilise un jeu de paramètres qui ne correspond pas au système cible.

Comparaison chiffrée entre plusieurs largeurs de CRC

Largeur CRC Nombre de valeurs possibles Probabilité théorique d’erreur aléatoire non détectée Hex digits nécessaires
CRC-8 256 1 / 256, soit 0,390625 % 2
CRC-16 65536 1 / 65536, soit 0,0015259 % 4
CRC-18 262144 1 / 262144, soit 0,0003815 % 5
CRC-24 16777216 1 / 16777216, soit 0,00000596 % 6
CRC-32 4294967296 1 / 4294967296, soit 0,0000000233 % 8

Cette table montre pourquoi le CRC 18 bits occupe une place intermédiaire intéressante. Il ajoute seulement 2 bits de plus qu’un CRC 16, mais divise par 4 la probabilité théorique d’une erreur aléatoire non détectée. Dans des protocoles contraints par la taille de trame, ce compromis peut être très pertinent.

Statistiques d’overhead selon la taille utile du message

Taille utile Overhead CRC-16 Overhead CRC-18 Overhead CRC-32
64 bits 25,00 % 28,125 % 50,00 %
128 bits 12,50 % 14,0625 % 25,00 %
256 bits 6,25 % 7,03125 % 12,50 %
512 bits 3,125 % 3,515625 % 6,25 %
1024 bits 1,5625 % 1,7578125 % 3,125 %

L’overhead d’un CRC 18 bits reste raisonnable sur des blocs moyens et grands. C’est exactement là que son intérêt devient visible : plus protecteur qu’un CRC 16, mais nettement moins coûteux qu’un CRC 32 quand chaque bit transmis a un prix.

Implémenter un CRC 18 bits en C, la bonne méthode

En C, la méthode la plus claire pour débuter est l’algorithme bit à bit. Il n’est pas le plus rapide, mais il est simple à vérifier. On choisit un entier non signé suffisamment grand, souvent uint32_t, puis on force le registre à rester sur 18 bits via un masque. Le bit de tête, lui, se trouve à la position 17 si l’on numérote à partir de 0.

La stratégie typique est la suivante :

  1. Initialiser le registre CRC avec init.
  2. Pour chaque octet, l’injecter dans la partie haute du registre.
  3. Répéter 8 fois : tester le bit de poids fort, décaler à gauche, puis XOR avec le polynôme si nécessaire.
  4. Masquer systématiquement le registre avec ((1u << 18) - 1) ou un équivalent plus sûr.
  5. Appliquer éventuellement refout, puis xorout.

Si vous visez les performances, vous pouvez ensuite passer à une version table driven. Mais dans un contexte de validation, de reverse engineering ou d’intégration initiale, la version bit à bit reste la référence, parce qu’elle réduit l’ambiguïté et facilite la comparaison avec une spécification technique.

Exemple de squelette C à partir des paramètres du calculateur

Une bonne pratique consiste à faire générer ou recopier un squelette minimal, puis à valider sur quelques vecteurs de test. Le calculateur ci dessus vous aide surtout à verrouiller les paramètres avant de coder la version embarquée.

#include <stdint.h>
#include <stddef.h>

static uint32_t wpc_crc18_compute(const uint8_t *data, size_t len,
                                  uint32_t poly, uint32_t init,
                                  uint32_t xorout, int refin, int refout) {
    uint32_t crc = init & 0x3FFFFu;
    uint32_t mask = 0x3FFFFu;
    uint32_t top = 0x20000u;

    for (size_t i = 0; i < len; ++i) {
        uint8_t b = data[i];
        if (refin) {
            uint8_t r = 0;
            for (int j = 0; j < 8; ++j) {
                r = (uint8_t)((r << 1) | ((b >> j) & 1u));
            }
            b = r;
        }

        crc ^= ((uint32_t)b << 10);
        for (int bit = 0; bit < 8; ++bit) {
            if (crc & top) {
                crc = ((crc << 1) ^ poly) & mask;
            } else {
                crc = (crc << 1) & mask;
            }
        }
    }

    if (refout) {
        uint32_t r = 0;
        for (int i = 0; i < 18; ++i) {
            r = (r << 1) | ((crc >> i) & 1u);
        }
        crc = r & mask;
    }

    return (crc ^ xorout) & mask;
}

Comment valider votre code C de façon professionnelle

  • Testez au moins une chaîne ASCII simple, par exemple 123456789, car elle est largement utilisée comme vecteur de référence générique.
  • Testez un message vide afin de vérifier le comportement de init et xorout.
  • Testez un tableau hexadécimal connu, afin d’écarter toute confusion sur l’encodage.
  • Comparez les résultats entre votre version C et une version JavaScript ou Python indépendante.
  • Ajoutez des tests unitaires qui verrouillent les paramètres, pas seulement le résultat final.

Pièges fréquents en environnement embarqué

Sur microcontrôleur, les erreurs les plus fréquentes ne viennent pas du XOR lui même, mais du contexte. Par exemple, un flux DMA peut être lu avec un octet de retard, un buffer circulaire peut insérer un octet supplémentaire, ou un cast signé peut produire un décalage indéfini. De plus, les optimisations du compilateur ne sauveront pas un algorithme mal paramétré. Si vous devez respecter une norme, partez de la fiche officielle, documentez chaque paramètre et comparez votre sortie avec au moins trois trames réelles.

Sources de référence et documentation utile

Pour approfondir le sujet, voici trois ressources sérieuses qui aident à comprendre la théorie des CRC, le choix des polynômes et les implications pratiques en ingénierie :

Conclusion

Le calcul CRC 18bit en C n’est pas difficile sur le plan algorithmique, mais il exige une discipline absolue sur les paramètres et sur la largeur effective du registre. Une implémentation robuste doit toujours masquer le registre à 18 bits, documenter précisément la convention du polynôme et proposer des tests reproductibles. Si votre objectif est d’intégrer le calcul dans un firmware, commencez avec une version bit à bit simple, comparez vos résultats avec un outil externe, puis optimisez seulement après validation.

Le calculateur présent sur cette page vous donne un point d’appui fiable pour vérifier vos trames, illustrer l’évolution du CRC à chaque octet grâce au graphique et préparer directement votre code C. En production, la qualité du résultat dépend moins de la syntaxe C que de la cohérence entre spécification, jeu de tests et implémentation binaire réelle.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top