Problème de traduction d'un Checksum Perl en langage C++

dreddfullmetal Messages postés 13 Date d'inscription mardi 29 juin 2010 Statut Membre Dernière intervention 30 juin 2010 - 29 juin 2010 à 11:54
dreddfullmetal Messages postés 13 Date d'inscription mardi 29 juin 2010 Statut Membre Dernière intervention 30 juin 2010 - 30 juin 2010 à 09:23
Bonjour a tous :)
Je suis nouveau sur le site et je viens a votre rencontre car je suis sur un code qui me pose problème depuis quelque jour déjà.

Alors voila mon tuteur de stage m'a demandé de transcrire un code en Perl en C++

Il s'agit d'un code allant chercher des informations sur un capteur et a les sortir après calcul dans une console.
En ce moment je bloque sur la fonction qui permet de calculer un CRC16.

Voici le code en Perl :

#!/usr/bin/perl -w

sub checksum16 ($) {
# calculates the checksum 16 of the given string argument
my @bytes = unpack("C*", $_[0]);
my $sum = 0;
foreach(@bytes) {
$sum += $_;
$sum %= 2**16;
}
return $sum;
}

J'ai essayé plusieurs choses mais même après plusieurs je n'arrive pas a avoir quelques chose de concret.
Cela fait 3 jours que je parcours le net a la recherche d'un tuto ou d'un prototype pour le faire mais je n'arrive pas a faire la correspondance.

Je vous montre une ébauche de ma transcription en C++ :

#include <stdio.h>
#include <math.h>

typedef unsigned int CRC;

CRC crc_16(unsigned char c);

CRC crc_16(unsigned char c)
{
   int i,j,k;

   for(i=0;i!=8;c>>=1,i++)
   {
        j = CRC+CRC;
k = pow(2,16);
     	j = CRC%k;
      	
CRC = j;

   }
   return CRC;
}


Voila si quelqu'un peut me donner quelques infos pour que je puisse avancer un peu cela m'aiderait beaucoup :)

Merci d'avance.




Avoir le refrain beau a rechercher des crosses....serait prendre a revers la haine a écoper...

10 réponses

dreddfullmetal Messages postés 13 Date d'inscription mardi 29 juin 2010 Statut Membre Dernière intervention 30 juin 2010
29 juin 2010 à 14:24
J'ai oublié de préciser que mon code en C++ me retourne toujours 0... :p

Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
0
dreddfullmetal Messages postés 13 Date d'inscription mardi 29 juin 2010 Statut Membre Dernière intervention 30 juin 2010
29 juin 2010 à 16:38
Petit Up car j'avance un peu mais ce n'est pas encore ca :p

J'ai un problème de concordance entre les 2 codes:

Quand j'exécute le code Perl, j'obtiens 116

#!/usr/bin/perl -w

sub checksum16 ($) {
# calculates the checksum 16 of the given string argument
my @bytes = unpack("C*", $_[0]);
my $sum = 0;
foreach(@bytes) {
$sum += $_;
$sum %= 2**16;
}
return $sum;
}
print checksum16 ("t");
print "\n";

et quand j'execute le code C++ avec le même parametre j'obtiens 4294967268

#include <stdio.h>
#include <math.h>
#include <string.h>

typedef const char CRC;

CRC crc_16(unsigned char c)
{
   int i,j,k = 0;

   for(i=0;i!=8;c>>=1,i++)
   {
        k += c;
k %= 1<<16;
   }
   return k;
}

int main()
{
printf("%u",crc_16('t'));
printf ("\n");
return 0;
}



Voila :p
Si quelqu'un sait ce qui ne va pas, qu'il n'hésite pas je suis ouvert a toute critique:p

Cordialement,
Dredd






Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
29 juin 2010 à 17:30
Si on reprend ton exemple en Perl (je met "toto" au lieu de "t"):
#!/usr/bin/perl -w

sub checksum16 ($) {
# calculates the checksum 16
# of the given string argument
    my @bytes = unpack("C*", $_[0]);
    my $sum = 0;
    foreach(@bytes) {
$sum += $_;
$sum %= 2**16;
    }
    return $sum;
}
print checksum16 ("toto");
print "\n";


On observe que l'utilisateur donne une chaîne de caractère et non un seul et unique caractère. Chacun des éléments est alors accumulé dans sum, puis un modulo de 2**16 est fait.
En C:
2**16 => 2 << 15 (et pas 16, fait le décalage sur un papier, tu verras :p)
Une chaine de caractère, c'est char*.

Au final, on peut faire:
#include <stdio.h>

unsigned int crc_16(char* s)
{
  unsigned int sum = 0;
  while (s && *s)
  {
    sum += *s;
    sum %= 2 << 15;
    ++s;
  }

  return sum;
}

int main(void)
{
  printf("%u\n", crc_16("toto"));

  return 0;
}


_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0
dreddfullmetal Messages postés 13 Date d'inscription mardi 29 juin 2010 Statut Membre Dernière intervention 30 juin 2010
29 juin 2010 à 17:38
J'ai enfin réussi :)
Mon problème venait du fait que je ne prenais pas en compte la longueur du caractère.

#include <cstdlib>
#include <cstdio>
#include <string>

typedef const char CRC;

CRC crc_16( char c)
{
   int i,j,k = 0;

   for(i=0;i<sizeof(c);i++)
   {

        k += c;
k %= 2<<16;
c>>=1;
   }
   return k;
}

int main()
{
printf("%d",crc_16('t'));
printf ("\n");
return 0;
}




Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
29 juin 2010 à 17:44
Voir mon commentaire :)
Ton code n'a pas besoin de la boucle, puisque sizeof (c) 1. Donc il n'y a jamais accumulation. Ce qui équivaudrait à faire: printf("%d",crc_16('t'));> printf("%d", 't');



_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0
dreddfullmetal Messages postés 13 Date d'inscription mardi 29 juin 2010 Statut Membre Dernière intervention 30 juin 2010
29 juin 2010 à 17:45
Edit : cela ne marche qui si on met 1 caractère xD

j'ai testé ton code, il marche parfaitement, je me chope un warning mais cela marche quand même :p

Merci beaucoup en tout cas:)

Je retourne a la suite de mon code en Perl:p
Je repasserais surement par ici d'ici peu xD

Cordialement,
Dredd


Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
29 juin 2010 à 17:47
je me chope un warning

Ça m'étonne, j'ai compilé en "-ansi -pedantic" (le mode le plus strict). Quel est le warning ?

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0
dreddfullmetal Messages postés 13 Date d'inscription mardi 29 juin 2010 Statut Membre Dernière intervention 30 juin 2010
29 juin 2010 à 17:52
je me chope ca :

romain@romain-laptop:~/Documents/Traduction Perl -> C++$ g++ -o test test_sum2.cpp
test_sum2.cpp: In function ‘int main()’:
test_sum2.cpp:18: warning: deprecated conversion from string constant to ‘char*’


Avoir le refrain beau a rechercher des crosses....serait prendre a rever la haine a écoper...
0
cptpingu Messages postés 3837 Date d'inscription dimanche 12 décembre 2004 Statut Modérateur Dernière intervention 28 mars 2023 123
29 juin 2010 à 17:59
A ba oui évidemment !
Tu compiles en C++, alors que c'est codé en C !!!

2 solutions:
- Tu le fais en C, et tu compiles avec:
gcc -W -Wall -ansi -pedantic test_sum2.c -o test


- Tu le fais en C++, et tu compiles avec:
g++ -W -Wall -Wabi -pedantic test_sum2.cpp -o test


Avec:
#include 

unsigned int crc_16(const std::string& s)
{
  unsigned int sum = 0;
  const unsigned int size = s.size();
  for (unsigned int i = 0; i < size; ++i)
  {
    sum += s[i];
    sum %= 2 << 15;
  }

  return sum;
}

int main()
{
  std::cout << crc_16("toto") << std::endl;

  return 0;
}


_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
0
dreddfullmetal Messages postés 13 Date d'inscription mardi 29 juin 2010 Statut Membre Dernière intervention 30 juin 2010
30 juin 2010 à 09:23
Merci beaucoup de toutes ces précisions CptPingu, cela m'aide beaucoup :)
Tu m'a l'air de t'y connaitre pas mal :p
Je repasserais par ici si j'ai d'autre soucis :)
A la revoyure

Cordialement,
Dredd


Avoir le refrain beau a rechercher des crosses....serait prendre a revers la haine a écoper...
0
Rejoignez-nous