OVH Cloud OVH Cloud

CRC16

6 réponses
Avatar
JPL INFO
quelqu'un connait-il l'algo pour calculer le CRC16 (egalement en CRC32) ?
je suis en train de dev un protocole de communication en X-MODEM (prg terminal
de windows)
--
Ce message a été posté via la plateforme Web club-Internet.fr
This message has been posted by the Web platform club-Internet.fr

http://forums.club-internet.fr/

6 réponses

Avatar
Eric LAURENT
Si cela peut t'aider, voici les sources d'une fonction optimisée qui calcule
le CRC16.

FONCTION CalculeCRC16(TrameCRC)

NBCar est un entier
Crc16 est un entier
AdrCRC est un entier
CarCRC est un entier
NumB est un entier
Retenue est un entier

Crc16=0xFFFF
AdrCRC=0xA001

POUR NBCar=1 A Taille(TrameCRC)
CarCRC=Asc(TrameCRC[[NBCar]])
Crc16=OuExclusifBinaire(Crc16,CarCRC)
SI Crc16<0 ALORS Crc16=Crc16+65536
NumB=0
TANTQUE NumB<=7
Retenue=ETBinaire(Crc16,1)
Crc16=PartieEntière(Crc16/2)
SI Retenue ALORS
Crc16=OuExclusifBinaire(Crc16,AdrCRC)
SI Crc16<0 ALORS Crc16=Crc16+65536
FIN
NumB++
FIN
FIN

RENVOYER(Caract(modulo(Crc16,256)) + Caract(PartieEntière(Crc16/256)))



JPL INFO wrote:
quelqu'un connait-il l'algo pour calculer le CRC16 (egalement en
CRC32) ?
je suis en train de dev un protocole de communication en X-MODEM (prg
terminal de windows)


Avatar
Romain PETIT
"JPL INFO" a émis l'idée suivante :
quelqu'un connait-il l'algo pour calculer le CRC16 (egalement en CRC32) ?
je suis en train de dev un protocole de communication en X-MODEM (prg
terminal de windows)



De la doc sur le calcul :
http://www.programmersheaven.com/search/download.asp?FileID&07

Chucks' "C" code:

/*
* This function calculates the CRC used by the XMODEM/CRC
Protocol
* The first argument is a pointer to the message block.
* The second argument is the number of bytes in the message
block.
* The function returns an integer which contains the CRC.
* The low order 16 bits are the coefficients of the CRC.
*/

int calcrc(ptr, count)
char *ptr;
int count;
{
int crc, i;


crc = 0;
while (--count >= 0) {
crc = crc ^ (int)*ptr++ << 8;
for (i = 0; i < 8; ++i)
if (crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
}
return (crc & 0xFFFF);
}



Un etraduction en W-Langage par Kristian Paradis (je n'ai pas vérifié
sa validité).

http://rbesset.net/modules/xoopsfaq/index.php?cat_id=5&PHPSESSIDTa20397d002a0b3ea8fd94f78d6d52e#q9

WD7x Code : Comment calculer le CRC 16 utilisé dans le protocole XModem
Extrait d'un post de Kristian Paradis sur le forum de daussy.org :
J'avais demandé il y a peu de l'aide pour calculer le CRC 16 utilisé
dans le protocole XModem.
J'ai finalement été capable d'adapter un algorithme de C++ que j'ai
trouvé alors voila, si quelqu'un d'autre en a besoin.
(Ou si vous trouvez une faille, vous pouvez m'en faire part! ;))


Procédure mCalculerCRC(_Chaine)
//Renvoie une chaine sur 2 octets.
eBit est un entier
eOctet est un entier
eCaract est un entier sans signe
eCRC est un entier sans signe
cChaine est une chaine = _Chaine
pour eOctet = 1 a taille(cChaine)
eCaract = asc(cChaine[[eOctet]])*0x100
eCRC = ouexbinaire(eCRC,eCaract)
pour eBit = 0 a 7
si etbinaire(eCRC,0x8000) <> 0 alors
eCRC = eCRC * 2
eCRC = ouexbinaire(eCRC,0x1021)
sinon
eCRC = eCRC * 2
FIN
fin
eCRC = etbinaire(eCrC,0xFFFF)
FIN
renvoyer caract(partieentiere(eCrC/256)) + caract(modulo(eCrc,256))


A+

--
Romain PETIT
http://cerbermail.com/?IJmancZl88
(cliquez sur le lien ci-dessus pour me contacter en privé)
Avatar
Fabrice Burghgraeve
bonjour .

"Eric LAURENT" a écrit dans le message de
news:bo5kku$iru$
Si cela peut t'aider, voici les sources d'une fonction optimisée qui


calcule
le CRC16.

FONCTION CalculeCRC16(TrameCRC)



(..)

Pourquoi ne pas utiliser la fonction scalculecrc16 de windev ?
a cause du type chaine ?
elle est moins rapide que la tienne ? (tu dis que t'as fonction est
optimisee...)
Parce que quand tu as fait ta fonction, tu ne savais pas que scalculecrc16
existait ?

--
Fabrice Burghgraeve
Computer & Services
suivez ce lien pour me repondre en prive :
http://cerbermail.com/?I3GMPRuXDD
Avatar
Eric LAURENT
La fonction que j'ai fourni calcule le CRC16 universel pour protocole
Modbus/Jbus, c'est un standard. La fonction de windev ne donne pas le même
résultat (1 entier) car c'est un calcul propriétaire, il s'agit plutot d'un
calcul de checksum comme un complément à 256.

Si vous devez communiquer avec des automates (omron, siemens, schneider,
merlin gerin, etc...), utilisez ma fonction, elle est éprouvée depuis
plusieurs années et c'est le standard CRC16 universel.



Fabrice Burghgraeve wrote:
bonjour .

"Eric LAURENT" a écrit dans le message de
news:bo5kku$iru$
Si cela peut t'aider, voici les sources d'une fonction optimisée qui
calcule le CRC16.

FONCTION CalculeCRC16(TrameCRC)



(..)

Pourquoi ne pas utiliser la fonction scalculecrc16 de windev ?
a cause du type chaine ?
elle est moins rapide que la tienne ? (tu dis que t'as fonction est
optimisee...)
Parce que quand tu as fait ta fonction, tu ne savais pas que
scalculecrc16 existait ?


Avatar
Romain PETIT
"Fabrice Burghgraeve" a écrit :
Parce que quand tu as fait ta fonction, tu ne savais pas que scalculecrc16
existait ?



Salut Fabrice,

Cette fonction est-elle standard ou spécifique W-Langage (comme un
serveur FP WD par exemple) ?
Je lis dans l'aide :
"Cette fonction permet de vérifier si une chaîne a été correctement
transmise lors de transmissions comportant des risques de perte
d'information (par modem par exemple) entre des *applications WinDev*."


A+

--
Romain PETIT
http://cerbermail.com/?IJmancZl88
(cliquez sur le lien ci-dessus pour me contacter en privé)
Avatar
Fabrice Burghgraeve
salut.

"Romain PETIT" a écrit dans le message de
news:
"Fabrice Burghgraeve" a écrit :
> Parce que quand tu as fait ta fonction, tu ne savais pas que


scalculecrc16
> existait ?

Salut Fabrice,

Cette fonction est-elle standard ou spécifique W-Langage (comme un
serveur FP WD par exemple) ?
Je lis dans l'aide :
"Cette fonction permet de vérifier si une chaîne a été correctement
transmise lors de transmissions comportant des risques de perte
d'information (par modem par exemple) entre des *applications WinDev*."




D'apres Eric Laurent, non elle n'est pas standard... PCSOFT a encore
re-invente la roue.
Je comprends mieux l'interet de la reecrire...

En tout cas, j'ai essayé les trois calculs de CRC (celui de windev, et les
deux proposés ici), et j'ai jamais la meme chose :
ch est une chaîne = "ABC"
Info("WD : "+sCalculeCrc16(ch));
Info("std : "+calculecrc16(ch));
Info("std2 : "+mcalculercrc(ch));

me donne :
WD : 5499
std : P. (le deuxieme caractere est 3 points)
std2 : 9"

en windev, c'est exprime en entier, et pour les deux autres, en chaine de 2
caracteres
Je ne me suis pas penche sur le code pour voir quel resultat est le bon, ni
ou j'aurais pu envoyer un mauvais argument...


Ces trois fonctions ne donnent pas le meme resultat quand on inverse deux
lettres du message, donc de ce cote la c'est OK...
Mais a l'heure actuelle, je suis bien incapable de dire laquelle utiliser...

--
Fabrice Burghgraeve
Computer & Services
suivez ce lien pour me repondre en prive :
http://cerbermail.com/?I3GMPRuXDD