CALCUL D'UN CRC16 (CYCLIC REDUNDANCY CHECK)

cs_franckydeluka Messages postés 228 Date d'inscription mardi 5 avril 2005 Statut Membre Dernière intervention 4 janvier 2008 - 2 mai 2005 à 15:49
SNARPORY Messages postés 8 Date d'inscription mardi 13 février 2007 Statut Membre Dernière intervention 10 août 2009 - 28 févr. 2007 à 12:41
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/31142-calcul-d-un-crc16-cyclic-redundancy-check

SNARPORY Messages postés 8 Date d'inscription mardi 13 février 2007 Statut Membre Dernière intervention 10 août 2009
28 févr. 2007 à 12:41
Une solution plus simple serait de modifier l'appel dans le programme

/ au lieu de
CRC = ValCRC16(Form1.ValCalcul.Text & "0000", Form1.Poly.Text)

/ nouvel appel
CRC = ValCRC16("FFFF" & Form1.ValCalcul.Text & "0000", Form1.Poly.Text)
SNARPORY Messages postés 8 Date d'inscription mardi 13 février 2007 Statut Membre Dernière intervention 10 août 2009
23 févr. 2007 à 17:10
bonjour , cela fait peut être trop longtemps que le sujet n'est pas commenté, mais je me permet de faire une remarques.

L'etude exhaustive de sources de provenance différentes et de langages différents ( VB ,DELPHI , C++ ) montre que l'initialisation n'est peut être pas effectuée correctement !!
n'ayant aucune application qui utilise le CRC_CCITT_V41 je n'ai pu vérifié !
( toutefois, ci dessous une suggestion de modification )

Function ValCRC16(UneChaine As String, Polynome As String) As String
Dim x As Long
' -------- au lieu de ValCRC16 = Mid(UneChaine, 1, 4)
ValCRC16 = &HFFFF ' initialisation
' --------- au lieu de For x = 17 To Len(UneChaine) * 4
For x = 17 To (( Len(UneChaine) +2 ) * 4) ' modification de la taille
If (PrefixHexa & ValCRC16 And &H8000) > 0 Then
ValCRC16 = BitLeft(ValCRC16, ValBit(UneChaine, x))
ValCRC16 = Hex((PrefixHexa & ValCRC16) Xor (PrefixHexa & Polynome))
ValCRC16 = String(4 - Len(ValCRC16), "0") & ValCRC16
Else
ValCRC16 = BitLeft(ValCRC16, ValBit(UneChaine, x))
End If
Next x
End Function
akuvido Messages postés 13 Date d'inscription lundi 6 mars 2006 Statut Membre Dernière intervention 18 avril 2006
10 avril 2006 à 11:55
D'accord merci quand meme pour ton aide

Bonne continuation
MarcVB Messages postés 10 Date d'inscription lundi 28 avril 2003 Statut Membre Dernière intervention 10 avril 2006
10 avril 2006 à 11:45
Bonjour akuvido

Depuis aout 2005, j'ai oublié les détails à propos de cette histoire. Je n'ai pas le temps de re-travailler le sujet en ce moment.
Le principe que tu évoques me semble, à la première lecture, correct.

Dans le principe, après avoir refait la division, vu que le résultat de la soustraction pour le bit de poids fort est toujours nul, et vu, que le bit de poids fort d'un polynome est toujours 1, j'ai certaiment simplifié le problème en réalisant une soustraction sur quatre bits et non sur cinq ... A vérifier si je ne me suis pas planté en programmant cela ...

Bonne réception
Marc VB
akuvido Messages postés 13 Date d'inscription lundi 6 mars 2006 Statut Membre Dernière intervention 18 avril 2006
10 avril 2006 à 11:20
Oui, Je suis désolé pour l'orthographe.

Je vais montrer comment j'ai compris la chose et tu me diras si ca te semble cohérant

Si le message à transferer est 11 0101 1011 (h'35B) et que le polynome générateur est 10011 :

Il faut d'abord decaler le message à transmettre de 4 rangs ( degres du polynome ou nombre de bits - 1 )

On se retrouve avec Ceci : 11 0101 1011 0000

On procede alors à une division de 11 0101 1011 0000 par 10011 (polynome ).

On recuperer le reste de la division qui est 1110.

On fait alors : 11 0101 1011 0000 Xor 1110

Ceci qui nous donne alors le message a transmettre suivi de son CRC : 11 0101 1011 1110


Je pense que j'ai bien compris la chose mais tu me dis que le bit de poids fort n'est pas utile.

Donc je demande comfirmation

Merci d'avance
MarcVB Messages postés 10 Date d'inscription lundi 28 avril 2003 Statut Membre Dernière intervention 10 avril 2006
10 avril 2006 à 08:47
Bonjour Akuvido,

En effet, je n'utilise pas le bit de poids fort. Je n'ai plus le détail en tête ... Toutefois, Il me semble qu'il ne sert pas dans le calcul. C'est du moins ce que j'ai compris dans le cours j'ai lu.

Attention aux accords : "... tu dis utiliser ...", "J'ai essayé de le modifier ..." "... ne me permet pas de le vérifier."

Bonne continuation
Marc VB
akuvido Messages postés 13 Date d'inscription lundi 6 mars 2006 Statut Membre Dernière intervention 18 avril 2006
9 avril 2006 à 22:02
Bonjour, si je peux me permettre une question :

dans ta source, tu dis utilisé le CRC CCITT qui corresponds a ce polynome (x^16 + x^12 + x^5 +1) ce qui en Hexa donne 11021 et non 1021.

Je me demande si le probleme ne viens pas de la mais ma mediocrité en programmation ne me permets pas de le verifié.

J'ai essayé de modifié le polynome dnas la source mais des que lon depasse 4 caractere, il refuse !

Voila A+
cs_sitemo Messages postés 341 Date d'inscription samedi 8 novembre 2003 Statut Membre Dernière intervention 29 juin 2011 1
7 févr. 2006 à 21:02
envoie moi stp momokarim@aol.com merci
MarcVB Messages postés 10 Date d'inscription lundi 28 avril 2003 Statut Membre Dernière intervention 10 avril 2006
26 août 2005 à 08:09
Bonjour à tous,

Comme l'indique le commentaire, ceci correspond à la première version du code. Je n'ai pas mis la deuxième version en ligne. Celle ci permet de "retourner" dans tous les sens le flux en entrée (par quartet ou par octet), de retourner le CRC final et d'autres options ...

Helas, comme ooly2001, je n'ai pas réussi à recalculer un CRC utilisable. Je me suis arrangé avec le constructeur de l'appareil qui nécessitait ce calcul pour obtenir une DLL qui s'occupe des problèmes de transmission.

Par manque de temps, je n'ai pas continué à chercher où est le BUG (ou plutot comment il faut calculer cette saloperie). En effet, le problème viens plutôt de la recette (comment on fait) que du coté d'un bug du programme (celui ci fait bien ce que je lui demande de faire). Il y a de multiples façon de calculer un CRC et visiblement même si il est indiqué "CRC CCITT", cela ne donne pas tous les paramètres.

Après avoir consulté pas mal d'ouvrages sur le sujet, je me suis apperçu qu'il y avait de gros éccart entre les différents documents. On ne retourve pas deux fois la même méthode de calcul (ce qui n'est pas grave) sauf que l'utilisation des différentes méthodes ne donne pas le même résultat !!

j'ai déja rencontré ce genre de problème au cours de mes études (en electronique). Des profs qui affirment des énormités et qui profitent d'une notoriété (certainement mérité) pour l'imposer et ne plus se remettre en question. C'est certainemet ce qui arrive ici. Du cout, fonction du cours que vous avez suivi vous ne calculez pas le même CRC qu'un autre.

J'ai quand même une documentation à vous conseiller. Un certain "Ross Williams" à ecrit un cours pas mal sur le calcul des CRC. Vous la trouverez sur le net (je peux vous l'envoyer aussi). Un exemple est donnée en C. Je n'ai helas plus utilisé ce langage depuis longtemps et ai un peut oublié comment il fonctionne. La aussi, je n'ai pas eut le temps de me replonger dans mes cours C pour transcrire l'exemple donné en VB.

Bonne chance dans vos travaux.
Marc
saucekorn69 Messages postés 2 Date d'inscription jeudi 25 août 2005 Statut Membre Dernière intervention 26 août 2005
25 août 2005 à 19:57
Salut !
Pour ma part, j'ai un problème de communication, et je soupçonne mon calcul de CRC. Les résultats attendus ne sont pas a la hauteur de mes espérances vu qu'il m'est impossible de valider un CRC qui m'est donné en exemple...
ooly2001 Messages postés 43 Date d'inscription lundi 24 janvier 2005 Statut Membre Dernière intervention 9 décembre 2011
21 juil. 2005 à 12:29
Salut !
ton prog est pas mal du tout mais le resultat qu'il me donne ne correspond pas a ce que j'attends, je m'explique, j'envoie une commande a un appareil via le port RS232 et pour chaque commande, un calcul CRC intervient. j'ai un exemple de commande avec le resultat du CRC que je n'arrive pas a reproduire sur ton prog

Mon exemple:
!COMMANDE^options|CRC soit --> !LOG_NUM_RECORDS^EVENT|F5DF
J'ai tester a peu pres toutes les possibilités (avec ou sans les ! | ^ etc...) mais je n'arrive pas a avoir un CRC de F5DF

Pourrais tu m'eclairer ?
Sachant en plus que dans le protocole de communication de mon appareil il y a ca:
Name CRC-CCITT
Width 16 bits
Polynomial x16 + x12 + x5 + 1 (0x11021)
Initial Value 0xFFFF
Reflect on input FALSE
Reflect on output FALSE
Xor Output width 0x0000
Check Not applicable

MERCI d'avance
cs_franckydeluka Messages postés 228 Date d'inscription mardi 5 avril 2005 Statut Membre Dernière intervention 4 janvier 2008 1
2 mai 2005 à 15:49
je cherchais à faire quelque chose de similaire pour mon projet.
jespère que ca me fera gagner du temps :)
Merci
Rejoignez-nous