Peut-être que je ne le vois tout simplement pas, mais CRC32 semble soit inutilement compliqué, soit insuffisamment expliqué partout où je pourrais trouver sur le Web.
Je comprends que c'est le reste d'une division arithmétique non basée sur le report de la valeur du message, divisé par le polynôme (générateur), mais l'implémentation réelle de celui-ci m'échappe.
J'ai lu un guide indolore sur les algorithmes de détection d'erreur CRC , et je dois dire que ce n'était pas indolore. Cela passe assez bien en revue la théorie, mais l'auteur n'arrive jamais à un simple «c'est ça». Il dit quels sont les paramètres de l'algorithme CRC32 standard, mais il néglige d'exposer clairement comment vous y parvenez.
La partie qui me comprend, c'est quand il dit "c'est ça" et ajoute ensuite, "oh au fait, ça peut être inversé ou démarré avec des conditions initiales différentes", et ne donne pas une réponse claire de la manière finale de calculer une somme de contrôle CRC32 compte tenu de tous les changements qu'il vient d'ajouter.
- Existe-t-il une explication plus simple de la façon dont le CRC32 est calculé?
J'ai essayé de coder en C comment la table est formée:
for (i = 0; i < 256; i++)
{
temp = i;
for (j = 0; j < 8; j++)
{
if (temp & 1)
{
temp >>= 1;
temp ^= 0xEDB88320;
}
else {temp >>= 1;}
}
testcrc[i] = temp;
}
mais cela semble générer des valeurs incompatibles avec les valeurs que j'ai trouvées ailleurs sur Internet. Je pourrais utiliser les valeurs que j'ai trouvées en ligne, mais je veux comprendre comment elles ont été créées.
Toute aide pour clarifier ces chiffres incroyablement déroutants serait très appréciée.
0xEDB88320
peut également être écrit msbit-first ( normal ) comme0x04C11DB7
. Les valeurs de table que vous avez trouvées ailleurs ont-elles été générées en utilisant le même polynôme CRC?Réponses:
Le polynôme pour CRC32 est:
Ou en hexadécimal et binaire:
Le terme le plus élevé (x 32 ) n'est généralement pas écrit explicitement, il peut donc être représenté en hexadécimal comme
N'hésitez pas à compter les 1 et les 0, mais vous constaterez qu'ils correspondent au polynôme, où
1
est le bit 0 (ou le premier bit) et lex
bit 1 (ou le deuxième bit).Pourquoi ce polynôme? Parce qu'il doit y avoir un polynôme donné standard et que le standard a été défini par IEEE 802.3. Il est également extrêmement difficile de trouver un polynôme qui détecte efficacement différentes erreurs sur les bits.
Vous pouvez considérer le CRC-32 comme une série d '«arithmétique binaire sans portage», ou fondamentalement «opérations XOR et décalage». C'est ce qu'on appelle techniquement l'arithmétique polynomiale.
Pour mieux le comprendre, pensez à cette multiplication:
Si nous supposons que x est la base 2, nous obtenons:
Pourquoi? Parce que 3x ^ 3 est 11x ^ 11 (mais nous n'avons besoin que de 1 ou 0 pré-chiffre), nous reportons donc:
Mais les mathématiciens ont changé les règles pour que ce soit le mod 2. Donc, fondamentalement, tout polynôme binaire mod 2 est juste une addition sans report ni XOR. Donc, notre équation originale ressemble à:
Je sais que c'est un acte de foi, mais cela dépasse mes capacités en tant que programmeur en ligne. Si vous êtes un étudiant ou un ingénieur en CS inconditionnel, je mets au défi de décomposer cela. Tout le monde bénéficiera de cette analyse.
Donc, pour élaborer un exemple complet:
Maintenant, nous divisons le Message augmenté par le Poly en utilisant l'arithmétique CRC. C'est la même division que précédemment:
La division donne un quotient, que nous jetons, et un reste, qui est la somme de contrôle calculée. Cela met fin au calcul. Habituellement, la somme de contrôle est ensuite ajoutée au message et le résultat est transmis. Dans ce cas, la transmission serait: 11010110111110.
Utilisez uniquement un nombre 32 bits comme diviseur et utilisez l'intégralité de votre flux comme dividende. Jetez le quotient et conservez le reste. Tack le reste à la fin de votre message et vous avez un CRC32.
Critique moyenne des gars:
(Notez que le flux doit être divisible par 32 bits ou il doit être complété. Par exemple, un flux ANSI 8 bits devrait être complété. Également à la fin du flux, la division est interrompue.)
la source
x^6 + x^5 + x^4 + 3*x^3 + x^2 + x^1 + x^0 ... If we assume x is base 2 then we get: x^7 + x^3 + x^2 + x^1 + x^0
. Ce n'est pas ainsi que les maths fonctionnent. Les coefficients du polynôme sont mod (2) ou GF (2), les x sont laissés seuls, ce qui donne x ^ 6 + x ^ 5 + x ^ 4 + x ^ 3 + x ^ 2 + x ^ 1 + x ^ 0 (puisque 3 mod (2) = 1).Tack the remainder on the end of your message
- techniquement, le reste est soustrait des 0 bits qui ont été ajoutés au message, mais comme il s'agit de maths mod (2), l'addition et la soustraction sont les mêmes que XOR, et les zéro bits XOR avec le reste sont les mêmes comme le reste.Why did you append four 0s though?
- les algorithmes logiciels pour calculer le crc ajoutent efficacement les 0, même si ce n'est pas apparent. Si vous affichez le calcul CRC en utilisant la division longue main, alors des 0 doivent être ajoutés pour que l'exemple de division apparaisse correctement.Pour IEEE802.3, CRC-32. Considérez le message entier comme un flux de bits série, ajoutez 32 zéros à la fin du message. Ensuite, vous DEVEZ inverser les bits de CHAQUE octet du message et faire un complément à 1 sur les 32 premiers bits. Divisez maintenant par le polynôme CRC-32, 0x104C11DB7. Enfin, vous devez compléter par 1 le reste de 32 bits de cette division en inversant chacun des 4 octets du reste. Cela devient le CRC 32 bits qui est ajouté à la fin du message.
La raison de cette étrange procédure est que les premières implémentations Ethernet sérialiseraient le message un octet à la fois et transmettraient d'abord le bit le moins significatif de chaque octet. Le train de bits série est ensuite passé par un calcul de registre à décalage CRC-32 série, qui a simplement été complété et envoyé sur le fil une fois le message terminé. La raison de compléter les 32 premiers bits du message est que vous n'obteniez pas un CRC tout à zéro même si le message était entièrement à zéro.
la source
Un CRC est assez simple; vous prenez un polynôme représenté sous forme de bits et de données, et vous divisez le polynôme en données (ou vous représentez les données sous forme de polynôme et faites la même chose). Le reste, qui est compris entre 0 et le polynôme est le CRC. Votre code est un peu difficile à comprendre, en partie parce qu'il est incomplet: temp et testcrc ne sont pas déclarés, donc on ne sait pas ce qui est indexé et combien de données sont exécutées dans l'algorithme.
La façon de comprendre les CRC est d'essayer d'en calculer quelques-uns en utilisant un court morceau de données (16 bits environ) avec un polynôme court - 4 bits, peut-être. Si vous pratiquez de cette façon, vous comprendrez vraiment comment vous pouvez procéder pour le coder.
Si vous le faites fréquemment, un CRC est assez lent à calculer dans un logiciel. Le calcul matériel est beaucoup plus efficace et ne nécessite que quelques portes.
la source
En plus du contrôle de redondance cyclique Wikipedia et du calcul des articles CRC , j'ai trouvé un article intitulé Reversing CRC - Theory and Practice * comme une bonne référence.
Il existe essentiellement trois approches pour calculer un CRC: une approche algébrique, une approche orientée bits et une approche basée sur les tables. Dans Reversing CRC - Theory and Practice * , chacun de ces trois algorithmes / approches est expliqué en théorie accompagné dans l'ANNEXE d'une implémentation du CRC32 dans le langage de programmation C.
* PDF Lien
inversant CRC - Théorie et pratique.
HU Berlin Public Report
SAR-PR-2006-05
Mai 2006
Auteurs:
Martin Stigge, Henryk Plötz, Wolf Müller, Jens-Peter Redlich
la source
J'ai passé un moment à essayer de trouver la réponse à cette question, et j'ai finalement publié un tutoriel sur CRC-32 aujourd'hui: Tutoriel de hachage CRC-32 - AutoHotkey Community
Dans cet exemple, je montre comment calculer le hachage CRC-32 pour la chaîne ASCII 'abc':
la source
^
? stackoverflow.com/questions/62168128/…Ensuite, il y a toujours Rosetta Code, qui montre crc32 implémenté dans des dizaines de langages informatiques. https://rosettacode.org/wiki/CRC-32 et contient des liens vers de nombreuses explications et implémentations.
la source
Afin de réduire crc32 à prendre le rappel, vous devez:
Dans le code c'est:
où reminderIEEE est le pur rappel sur GF (2) [x]
la source