2010-12-08 9 views
0

Ceci est le code C# J'utilise:Comment puis-je convertir cette Crypto de C# à C

public void Decrypt(byte[] @in, byte[] @out, int size) 
{ 
    lock (this) 
    { 
     for (ushort i = 0; i < size; i++) 
     { 
      if (_server) 
      { 
       @out[i] = (byte)(@in[i]^0xAB); 
       @out[i] = (byte)((@out[i] << 4) | (@out[i] >> 4)); 
       @out[i] = (byte)(ConquerKeys.Key2[_inCounter >> 8]^@out[i]); 
       @out[i] = (byte)(ConquerKeys.Key1[_inCounter & 0xFF]^@out[i]); 
      } 
      else 
      { 
       @out[i] = (byte)(ConquerKeys.Key1[_inCounter & 0xFF]^@in[i]); 
       @out[i] = (byte)(ConquerKeys.Key2[_inCounter >> 8]^@out[i]); 
       @out[i] = (byte)((@out[i] << 4) | (@out[i] >> 4)); 
       @out[i] = (byte)(@out[i]^0xAB); 
      } 
      _inCounter = (ushort)(_inCounter + 1); 
     } 
    } 
} 

ce qui est la façon dont je me suis converti à travailler en C.

char* decrypt(char* in, int size, int server) 
{ 
    char out[size]; 
    memset(out, 0, size); 
    for (int i = 0; i < size; i++) 
    { 
     if (server == 1) 
     { 
      out[i] = in[i]^0xAB; 
      out[i] = out[i] << 4 | out[i] >> 4; 
      out[i] = Key2[incounter >> 8]^out[i]; 
      out[i] = Key1[incounter & 0xFF]^in[i]; 
     } 
     else if (server == 0) 
     { 
      out[i] = Key1[incounter & 0xFF]^in[i]; 
      out[i] = Key2[incounter >> 8]^out[i]; 
      out[i] = out[i] << 4 | out[i] >> 4; 
      out[i] = out[i]^0xAB; 
     } 
     incounter++; 
    } 
    return out; 
} 

Cependant, pour certains raison que le C ne fonctionne pas.

Link for the full C# file

Link for the full C file

Link for the C implementation

+2

On dirait que la source C# a été transférée de C. Oh, comme c'est amusant! Un jeu de téléphone! – cdhowie

+0

Avez-vous des tests unitaires? – khachik

+0

@khachik, non je ne sais pas. – Basser

Répondre

3

Une erreur de traduction s'est produite.

C# ligne:

@out[i] = (byte)(ConquerKeys.Key1[_inCounter & 0xFF]^@out[i]); 

Est devenu:

out[i] = Key1[incounter & 0xFF]^in[i]; 

La valeur à droite de la XOR (^) est du mauvais tableau.

En outre, vous renvoyez une variable allouée par pile, ce qui provoque toutes sortes de problèmes.

Change:

char out[size]; 
memset(out, 0, size); 

à:

char *out = (char*)calloc(size, sizeof(char)); 
+0

Merci beaucoup! J'aurais dû le découvrir moi-même ... depuis plus d'une heure. Désolé de vous déranger tous .. – Basser

+0

Pas de problème. Lorsque vous observez le même code depuis longtemps, il est facile de devenir aveugle à ce genre d'erreur. Les yeux frais aident toujours. – jtdubs

+0

En fait, je viens de découvrir que cela ne l'a pas résolu. Cela a semblé être correct. Mais ça ne marche toujours pas. : / – Basser

3

L'erreur la plus flagrante que je vois est que vous retournez un pointeur vers un tableau de pile alloué, qui va se piétiné par le prochain appel de fonction après decrypt() renvoie. Vous devez malloc() tampon ou passer dans un pointeur vers un tampon inscriptible.

+0

Pourriez-vous m'aider en utilisant un exemple? C'est le premier projet impliquant du code non managé. :/ – Basser

+1

Bien sûr. Remplacez char out [size]; 'par char = out = (char *) malloc (taille * sizeof (char)); Notez que le code qui appelle 'decrypt()' sera responsable de 'free()' ing la mémoire quand elle est terminée avec elle. – cdhowie

+0

@cdhowie, ne fonctionne toujours pas ... J'ai modifié mon message original et ajouté ma mise en œuvre. – Basser

1

Vous renvoyez une référence à une variable locale qui est illégale. Laissez l'appelant passer dans un tableau ou utilisez malloc() pour créer un tableau dans la méthode.

+2

Non, le retour d'une variable locale n'est pas illégal. Renvoyer un ** pointeur vers une variable allouée par une pile ** est illégal. (Ou, à tout le moins, un comportement indéfini.) Notez également la différence entre "local" et "stack-assigned" - le premier inclut des variables statiques de portée fonctionnelle; ce dernier ne le fait pas. – cdhowie

1

Je suggère également tourner char en unsigned char car il est plus facile à transporter. Si votre plate-forme suppose que char est la même chose que signed char, l'arithmétique (changements de bits, etc.) ne fonctionnera pas correctement.
Donc, il suffit de spécifier unsigned char explicitement (utilisez un typedef ou incluez <stdint.h> si unsigned char semble trop long pour vous).

Questions connexes