2009-09-26 8 views
1

Cela peut sembler une question stupide, mais je ne peux pas trouver le anwer ...Valeur de retour de XXTEA

Voici le code pour XXTEA de Wikipedia:

#include <stdint.h> 
#define DELTA 0x9e3779b9 
#define MX ((z>>5^y<<2) + (y>>3^z<<4))^((sum^y) + (k[(p&3)^e]^z)); 

void btea(uint32_t *v, int n, uint32_t const k[4]) { 
    uint32_t y, z, sum; 
    unsigned p, rounds, e; 
    if (n > 1) {   /* Coding Part */ 
    rounds = 6 + 52/n; 
    sum = 0; 
    z = v[n-1]; 
    do { 
     sum += DELTA; 
     e = (sum >> 2) & 3; 
     for (p=0; p<n-1; p++) 
     y = v[p+1], z = v[p] += MX; 
     y = v[0]; 
     z = v[n-1] += MX; 
    } while (--rounds); 
    } else if (n < -1) { /* Decoding Part */ 
    n = -n; 
    rounds = 6 + 52/n; 
    sum = rounds*DELTA; 
    y = v[0]; 
    do { 
     e = (sum >> 2) & 3; 
     for (p=n-1; p>0; p--) 
     z = v[p-1], y = v[p] -= MX; 
     z = v[n-1]; 
     y = v[0] -= MX; 
    } while ((sum -= DELTA) != 0); 
    } 
} 

Je PORTAGE ce à C# . Je ne sais pas ce que je néglige, mais où est le résultat du cryptage stocké? Je suppose que c'est en v, mais les données de v ne sont jamais définies, seulement lues.

Qu'est-ce que je ne vois pas?

Répondre

1

Les opérateurs = - = + = ont la même priorité dans les expressions et ils sont associés de droite à gauche selon la norme C++ 5.17 (et je crois qu'il y a la même règle dans C). Par exemple, ceci:

y = v[p] -= MX; 

pourrait être remplacé par:

v[p] -= MX; // <<< modification of data here 
y = v[p]; 
2

Dans la partie codante: z = v[n-1] += MX;

Dans la partie de décodage: y = v[p] -= MX;

Ces lignes exécutent + = sur un élément de la matrice de v, puis copier la nouvelle valeur dans z ou y. Celui qui a écrit le code privilégiait la brièveté par rapport à la clarté, ce qui n'est généralement pas une bonne chose dans la pratique.

+0

Merci beaucoup. Comment ne pas avoir vu cela ... – Ruud

1

v est défini dans cette ligne, par exemple:

y = v[0] -= MX; 

Cela pourrait aussi être écrit:

v[0] = v[0] - MX; 
y = v[0]; 
1

Les données dans le tableau à la fin du pointeur v est mis à jour, bien que:

v[p] += MX; 
... 
z = v[n-1] += MX; 
... 
z = v[p-1], y = v[p] -= MX; 
... 
y = v[0] -= MX; 

Alors oui; ce sont les données référence être v qui est mis à jour.

7

J'ai trouvé cette page pendant que vous recherchiez "XXTEA C#" dans Google. Impossible de trouver des implémentations readymade, alors j'ai fait le mien. Avec la magie des fermetures, c'est une copie pratiquement textuelle du code de référence. Je l'ai posté pour quelqu'un d'autre qui arrive ici. Notez que bien que cela accepte un tableau d'octets de longueur arbitraire, la longueur du tableau retourné sera toujours un multiple de quatre. Et, contrairement à l'implémentation de référence, celle-ci renvoie des données modifiées au lieu de changer l'original.

using System; 

namespace Encryption 
{ 
    public enum XXTEAMode 
    { 
     Encrypt, 
     Decrypt 
    } 

    static public class XXTEA 
    { 
     static public byte[] Code(byte[] data, uint[] k, XXTEAMode mode) 
     { 
      uint[] v = new uint[(int)Math.Ceiling((float)data.Length/4)]; 
      Buffer.BlockCopy(data, 0, v, 0, data.Length); 

      unchecked 
      { 
       const uint DELTA = 0x9e3779b9; 
       uint y = 0, z = 0, sum = 0, p = 0, rounds = 0, e = 0; 
       int n = v.Length; 
       Func<uint> MX =() => (((z >> 5^y << 2) + (y >> 3^z << 4))^((sum^y) + (k[(p & 3)^e]^z))); 

       if (mode == XXTEAMode.Encrypt) 
       { 
        rounds = (uint)(6 + 52/n); 
        z = v[n - 1]; 
        do 
        { 
         sum += DELTA; 
         e = (sum >> 2) & 3; 
         for (p = 0; p < n - 1; p++) 
         { 
          y = v[p + 1]; 
          z = v[p] += MX(); 
         } 
         y = v[0]; 
         z = v[n - 1] += MX(); 
        } while (--rounds > 0); 
       } 
       else 
       { 
        rounds = (uint)(6 + 52/n); 
        sum = rounds * DELTA; 
        y = v[0]; 
        do 
        { 
         e = (sum >> 2) & 3; 
         for (p = (uint)(n - 1); p > 0; p--) 
         { 
          z = v[p - 1]; 
          y = v[p] -= MX(); 
         } 
         z = v[n - 1]; 
         y = v[0] -= MX(); 
        } while ((sum -= DELTA) != 0); 
       } 
      } 

      byte[] rvl = new byte[v.Length * 4]; 
      Buffer.BlockCopy(v, 0, rvl, 0, rvl.Length); 
      return rvl; 
     } 
    } 
} 
+0

Une note rapide, cette implémentation échouera avec v de longueur 1. Ajout d'un départ anticipé pour ce cas le corrige. – Stryck

+0

Merci, bonne référence et m'a fait gagner du temps! – Mausimo

Questions connexes