|
Iniciado por Mouhi, 19,sep. 2019 22:52 - 16 respuestas |
| |
| | | |
|
| |
Miembro registrado 81 mensajes Popularité : +7 (7 votes) |
|
Publicado el 19,septiembre 2019 - 22:52 |
Bonjour,
Matheux wanted
Dans le cadre d'une communication avec une balise GPS, je cherche à calculer le CRC-16 d'une chaine Hexa :
sHexaMsg is string = 0C010500000009676574696E666F0D0A01
On peut vérifier le résultat sur ce site : http://www.tahapaksu.com/crc/
Mais pas moyen d'obtenir le CRC-16 = 00 00 DA 7E (en Hexa).
J'ai essayé la fonction Windev sComputeCrc16 mais le résultat m'affiche d'autres chiffres :
sHexaMsg is string = "0C010500000009676574696E666F0D0A01" sDecimal is string = "4084743592531350520179175524571022166529" sBinary is string = "110000000001000001010000000000000000000000000000100101100111011001010111010001101001011011100110011001101111000011010000101000000001"
FOR i=1 _TO_ Length(sHexaMsg) STEP 2 sResult += Charact(Val(sHexaMsg[[i ON 2]],"x")) sResult += Asc(Val(sHexaMsg[[i ON 2]],"x")) END
Trace(sComputeCrc16(sResult))
J'ai trouvé ça sur le forum mais malheureusement je n'obtiens toujours pas mon résultat attendu (00 00 DA 7E) :
Procedure CRC16(sChaîne) tabTableCRC est un tableau de 256 entiers sans signe sur 2 nCRC, nC sont des entiers sans signe sur 2 nPoly est un entier sans signe sur 2 = 0xA001
POUR i = 0 A 255 nCRC = 0 nC = i POUR j = 0 A 7 SI ((nCRC || nC) & 0x0001) <> 0 ALORS nCRC = (nCRC bitDécaleDroite 1) || nPoly SINON nCRC = nCRC bitDécaleDroite 1 FIN nC = nC bitDécaleDroite 1 FIN tabTableCRC[i + 1] = nCRC FIN nCRC = 0 POUR j = 1 _A_ Taille(sChaîne) nC = Asc(sChaîne[[j]]) & 0xFF nCRC = (nCRC bitDécaleDroite 8) || tabTableCRC[((nCRC || nC) & 0xFF) + 1] FIN RENVOYER nCRC
Quelqu'un peut me sauver ?
Merci d'avance. |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 3.844 mensajes Popularité : +227 (347 votes) |
|
Publicado el 20,septiembre 2019 - 10:04 |
Bonjour, j'ai parcouru rapidement ton code. Qu'est ce que cela donne en remplaçant :FOR i=1 _TO_ Length(sHexaMsg) STEP 2 sResult += Charact(Val(sHexaMsg[[i ON 2]],"x")) sResult += Asc(Val(sHexaMsg[[i ON 2]],"x")) END Par
FOR i=1 _TO_ Length(sHexaMsg) STEP 2 sResult += Charact(Val(sHexaMsg[[i ON 2]],"x")) END
-- Il y a peut être plus simple, mais, ça tourne |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 324 mensajes Popularité : +21 (51 votes) |
|
Publicado el 20,septiembre 2019 - 13:18 |
Pourquoi vouloir réinventer la roue ? sCalculeCrc16(Chaine)
Edit : Ok y'a bien 20 méthodes de calcule de CRC, bien entendu on ne le retrouve pas avec le CRC16 de windev
"CRC-16/ARC" < c'est ce type d'algo qui va vous donner le résultat attendu ^^
Après test je ne retrouve pas qu'elle algo utilise windev avec celà
gbufMEssageChaine est un Buffer = HexaVersBuffer("0C010500000009676574696E666F0D0A01") gbufMEssageChaine = sCalculeCrc16(gbufMEssageChaine) BufferVersHexa(gbufMEssageChaine)
"<12><1><5><0><0><0><TAB>getinfo<RC><1> " < le hexaVersBuffer me renvoie celà une fois converti ca me semble bon, par contre au retour du CRC 16 j'obtiens FF25 et non pas la donnée attendu alors soit on peut préciser l'algo de calcule du CRC à windev et c'est bon sinon ouais va falloir voir comment cet algo calcule le crc16 ^^
Désolé pour mon premier message !Mensaje modificado, 20,septiembre 2019 - 13:39 |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 3.844 mensajes Popularité : +227 (347 votes) |
|
Publicado el 20,septiembre 2019 - 13:29 |
L'instruction est dans son premier code, le problème, c'était la conversion Hexa->Chaine. Le tout est de savoir si elle est nécessaire ou pas, en fonction de son traîtement.
-- Il y a peut être plus simple, mais, ça tourneMensaje modificado, 20,septiembre 2019 - 13:32 |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 324 mensajes Popularité : +21 (51 votes) |
|
Publicado el 20,septiembre 2019 - 14:55 |
Ouais j'avais pas vu le sCompute c'est pour celà, et d'ou aussi mon excuse dans le message à la fin . |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 3.844 mensajes Popularité : +227 (347 votes) |
|
Publicado el 20,septiembre 2019 - 15:02 |
Un croisement de message je n'avais pas vu la modif, et mon post a mis du temps à être validé. J'ai un rso rikiki aujourd'hui
-- Il y a peut être plus simple, mais, ça tourneMensaje modificado, 20,septiembre 2019 - 15:03 |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 81 mensajes Popularité : +7 (7 votes) |
|
Publicado el 20,septiembre 2019 - 17:42 |
Bonjour,
Merci pour les réponses,
Bien sûr, j'ai essayé une ligne à la fois (et pas les deux) :
sResult += Charact(Val(sHexaMsg[[i ON 2]],"x"))
sResult += Asc(Val(sHexaMsg[[i ON 2]],"x"))
@Voroltinquo, tu dis il y a peut-être plus simple mais ça tourne, c'est-à-dire ? En effet ça tourne mais c'est pas le bon résultat.
Toujours en attente d'une solution miracle
Merci d'avance. |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 3.844 mensajes Popularité : +227 (347 votes) |
|
Publicado el 20,septiembre 2019 - 21:49 |
Poncherello a expliqué pourquoi. En regardant ce site https://crccalc.com/ tu vas comprendre. Selon le mode de calcul on obtient des résultats différents.
La partie principale de l’algorithme d'un calcul de CRC est la suivante
FONCTION crc(tableau de bits bitString[1..longueur], entier polynome) { shiftRegister := valeur_initiale pour i de 1 à longueur { SI bit de poids fort de shiftRegister xor bitString[i] vaut 1 { shiftRegister := (shiftRegister décalé d'1 bit vers la Gauche) xor polynome } SINON { shiftRegister := (shiftRegister décalé d'1 bit vers la Gauche) } } retourne shiftRegister } On vois que si l'on change la valeur initiale ou le polynôme le résultat va changer.
Dans ton deuxième code, en passant la valeur de nPoly à 0x8005 ça devrait fonctionner.
-- Il y a peut être plus simple, mais, ça tourneMensaje modificado, 20,septiembre 2019 - 22:10 |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 81 mensajes Popularité : +7 (7 votes) |
|
Publicado el 21,septiembre 2019 - 00:47 |
Merci pour ton aide,
J'ai déjà vu le principe de ton algorithme (de Wikipedia), mais je n'ai pas réussi à l'implémenter,
Comme il y a plusieurs algo CRC-A, CRC-16/MODBUS CRC-16/ARC, c'est-ce dernier seulement qui affiche le résultat attendu.
J'ai suivi ton conseil, j'ai mis la valeur nPoly à 0x8005 (dans mon deuxième code), je m'approche mais ce n'est pas le bon résultat
nCRC, nC are 2-byte unsigned int tabTableCRC is array of 256 2-byte unsigned int nPoly is 2-byte unsigned int = 0x8005
sHexaMsg is string = "0C010500000009676574696E666F0D0A01"
FOR i = 0 TO 255 nCRC = 0 nC = i FOR j = 0 TO 7 IF ((nCRC || nC) & 0x0001) <> 0 THEN nCRC = (nCRC bitRightShift 1) || nPoly ELSE nCRC = nCRC bitRightShift 1 END nC = nC bitRightShift 1 END tabTableCRC[i + 1] = nCRC END
FOR j = 1 _TO_ Length(sHexaMsg) nC = Asc(sHexaMsg[[j]]) & 0xFF nCRC = (nCRC bitRightShift 8) || tabTableCRC[((nCRC || nC) & 0xFF) + 1] END
Trace(nCRC)
Un autre conseil ?
Merchiiii.Mensaje modificado, 21,septiembre 2019 - 00:57 |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 3.844 mensajes Popularité : +227 (347 votes) |
|
Publicado el 21,septiembre 2019 - 08:37 |
[A vue de nez] Normalement, la fonction attend une chaîne de type buffer et non une valeur hexadécimale, un hexaversbuffer avant le traitement serait sans doute souhaitable. bufMsg=HexaVersBuffer(sMsgHexa) Le traitement se fera alors sur le buffer bufMsg [/A vue de nez] Je n'ai pas vérifié la validité du traitement
-- Il y a peut être plus simple, mais, ça tourneMensaje modificado, 21,septiembre 2019 - 08:44 |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 81 mensajes Popularité : +7 (7 votes) |
|
Publicado el 21,septiembre 2019 - 12:35 |
Bonjour,
J'ai essayé avec un Buffer (plusieurs façons) mais toujours le résultat est différent,
nCRC, nC are 2-byte unsigned int tabTableCRC is array of 256 2-byte unsigned int nPoly is 2-byte unsigned int = 0x8005
bufReplay is Buffer = [0x0C,0x01,0x05,0x00,0x00,0x00,0x09,0x67,0x65,0x74,0x69,0x6E,0x66,0x6F,0x0D,0x0A,0x01]
FOR i = 0 TO 255 nCRC = 0 nC = i FOR j = 0 TO 7 IF ((nCRC || nC) & 0x0001) <> 0 THEN nCRC = (nCRC bitRightShift 1) || nPoly ELSE nCRC = nCRC bitRightShift 1 END nC = nC bitRightShift 1 END tabTableCRC[i + 1] = nCRC END
FOR j = 1 _TO_ Length(bufReplay) nC = Asc(bufReplay[[j]]) & 0xFF nCRC = (nCRC bitRightShift 8) || tabTableCRC[((nCRC || nC) & 0xFF) + 1] END
Trace(nCRC)
Dommage que la fonction Windev sCalculeCrc16(Chaine) ne reçoit pas un paramètre en plus (une constante) pour définir l'algo CRC.
@Voroltinquo, merci en tout cas |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 3.844 mensajes Popularité : +227 (347 votes) |
|
Publicado el 21,septiembre 2019 - 16:20 |
Il te manque l'initialisation du crc avant la boucle POUR j...
-- Il y a peut être plus simple, mais, ça tourne |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 81 mensajes Popularité : +7 (7 votes) |
|
Publicado el 21,septiembre 2019 - 17:55 |
Hello,
@Voroltinquo, je vois que tu ne lâche pas toi aussi
J'ai essayé avec et sans initialisation de nCRC, cette fois-ci j'obtiens 61673 à la place 55934
nCRC, nC are 2-byte unsigned int tabTableCRC is array of 256 2-byte unsigned int nPoly is 2-byte unsigned int = 0x8005
bufReplay is Buffer = [0x0C,0x01,0x05,0x00,0x00,0x00,0x09,0x67,0x65,0x74,0x69,0x6E,0x66,0x6F,0x0D,0x0A,0x01]
FOR i = 0 TO 255 nCRC = 0 nC = i FOR j = 0 TO 7 IF ((nCRC || nC) & 0x0001) <> 0 THEN nCRC = (nCRC bitRightShift 1) || nPoly ELSE nCRC = nCRC bitRightShift 1 END nC = nC bitRightShift 1 END tabTableCRC[i + 1] = nCRC END
nCRC = 0 FOR j = 1 _TO_ Length(bufReplay) nC = Asc(bufReplay[[j]]) & 0xFF nCRC = (nCRC bitRightShift 8) || tabTableCRC[((nCRC || nC) & 0xFF) + 1] END
Trace(nCRC) |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 3.844 mensajes Popularité : +227 (347 votes) |
|
Publicado el 21,septiembre 2019 - 19:31 |
Essaye déjà de tester la validité de la procédure avec des chaines classiques, la transformation hexa->Chaine pourra être traitée ultérieurement. Si la procédure ne fonctionne pas, il est inutile de s'entêter, il suffira de reprendre l'algo de base et de le convertir en Windev. Je crois que cette solution aurait été plus rapide
-- Il y a peut être plus simple, mais, ça tourne |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 3.844 mensajes Popularité : +227 (347 votes) |
|
Publicado el 23,septiembre 2019 - 07:09 |
En relisant le code, j'ai constaté une erreur de taille. La division binaire se fait via un décalage à gauche or dans notre cas nous avons un décalage à droite Par ailleurs, Mouhi a écrit :
Dommage que la fonction Windev sCalculeCrc16(Chaine) ne reçoit pas un paramètre en plus (une constante) pour définir l'algo CRC.
Il est fort probable que Windev utilise la norme internationale, à savoir le polynôme=0xA001
-- Il y a peut être plus simple, mais, ça tourneMensaje modificado, 23,septiembre 2019 - 07:32 |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 81 mensajes Popularité : +7 (7 votes) |
|
Publicado el 23,septiembre 2019 - 18:06 |
youpi
J'ai remis le polynôme 0xA001 et ça fonctionne. J'ai gardé le même décalage mais, le dernier polynôme n'était pas correct. Je suis en colère, au final c'est exactement le même code que j'ai posté dans le premier post. ça n'a pas fonctionné au départ car j'ai passé mon code Hexa en String à la place d'un Buffer.
Le code final (ça peut être utile pour quelqu'un d'autre qui tombe sur ce topic) :
nCRC, nC are 2-byte unsigned int tabTableCRC is array of 256 2-byte unsigned int nPoly is 2-byte unsigned int = 0xA001
bufReplay is Buffer = [0x0C,0x01,0x05,0x00,0x00,0x00,0x09,0x67,0x65,0x74,0x69,0x6E,0x66,0x6F,0x0D,0x0A,0x01]
FOR i = 0 TO 255 nCRC = 0 nC = i FOR j = 0 TO 7 IF ((nCRC || nC) & 0x0001) <> 0 THEN nCRC = (nCRC bitRightShift 1) || nPoly ELSE nCRC = nCRC bitRightShift 1 END nC = nC bitRightShift 1 END tabTableCRC[i + 1] = nCRC END
nCRC = 0 FOR j = 1 _TO_ Length(bufReplay) nC = Asc(bufReplay[[j]]) & 0xFF nCRC = (nCRC bitRightShift 8) || tabTableCRC[((nCRC || nC) & 0xFF) + 1] END
Trace(nCRC)
Un grand merci @Voroltinquo |
| |
| |
| | | |
|
| | |
| |
Miembro registrado 3.844 mensajes Popularité : +227 (347 votes) |
|
Publicado el 24,septiembre 2019 - 12:55 |
La valeur 0XA001 est l'inverse bit à bit de 0x8005, (ie 0xA001 = 1010 0000 0000 0001 et 0x8005 = 1000 0000 0000 0101) d'où le décalage à droite et non à gauche
-- Il y a peut être plus simple, mais, ça tourne |
| |
| |
| | | |
|
| | | | |
| | |
|