2012-02-09 16 views
6

È possibile generare una permutazione specifica di un array con una macro in C?Permutazioni di array C con macro

cioè Se ho una matrice X con gli elementi:

 0 1 2 3 4 5 
x = ["0","1","1","0","1","0"] 

Stavo pensando ci può essere qualche foo macro per qualcosa di simile:

#define S_2Permute(x) = [x[5], x[3], x[4], x[2], x[1]] 

dove ho ridefinire l'ordine dell'array , quindi l'elemento nella posizione originale 5 è ora nella posizione 0.

Qualche idea?

USO ESEMPIO

Sto iniziando a creare un'implementazione dell'algoritmo di crittografia DES. DES richiede parecchie permutazioni/espansioni in cui dovrei riordinare tutti gli elementi dell'array, a volte riducendo l'array e talvolta espandendolo. Speravo di essere in grado di definire una macro per permutare gli array per me.

EDIT2

Bene in DES il primo passo è una cosa chiamata permutazione iniziale. Così inizialmente ho qualche chiave a 64 bit, che per questo esempio può essere 0-15 esadecimale:

ABCDEF 

che si espande a:

0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 1010 1011 1100 1101 1110 1111 

IP (permutazione iniziale) sarebbe permutare questa stringa in modo che ogni elemento della matrice si troverebbe in una nuova posizione:

IP = 
      58 50 42 34 26 18 10 2 
      60 52 44 36 28 20 12 4 
      62 54 46 38 30 22 14 6 
      64 56 48 40 32 24 16 8 
      57 49 41 33 25 17  9 1 
      59 51 43 35 27 19 11 3 
      61 53 45 37 29 21 13 5 
      63 55 47 39 31 23 15 7 

Così il nuovo primo elemento della bitstring sarebbe l'elemento di 58 ° (bit) dal bitstring originale.

così avrei tutti questi bit memorizzati in un array di caratteri:

x = [0,0,0,0,0,0,0,1,0,0,1,0,0,0,1,1,0,1,0,0,0,1,0,1,0,1,1,0,0, 
    1,1,1,1,0,0,0,1,0,0,1,1,0,1,0,1,0,1,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,1,1] 

e poi basta chiamare

IP_PERMUTE(x); 

E macro magia si sono spostati tutti i bit nel nuovo posizioni corrette

+0

Non sono sicuro di averlo capito. Potresti fornire un esempio di come vorresti utilizzarlo? –

+0

@GregHewgill sicuro, ho aggiunto quello per cui spero di usarlo. –

+0

Stavo pensando più ad un esempio di codice. Come * esattamente * apparirebbe il tuo codice e quale parte sostituirebbe la macro? –

risposta

4

Assolutamente, sei quasi arrivato con il tuo esempio. Prova questo:

#define S_2Permute(x) {x[5], x[3], x[4], x[2], x[1]} 

Poi più tardi:

int x[] = {1,2,3,4,5,6}; 
int y[] = S_2Permute(x); // y is now {6,4,5,3,2} 

Due cose da ricordare:

1) in C, gli array sono numerati da 0, quindi è possibile che voleva dire:

#define S_2Permute(x) {x[4], x[2], x[3], x[1], x[0]} 

2) Se si utilizza gcc, è possibile compilare con -E per vedere l'output dal preprocessore (molto buono per debu gging macro espansioni).


Tuttavia, non credo che avrei fatto fare in questo modo - direi che il codice sarà più facile da leggere (e potenzialmente meno soggetto a errori) se generate le permutazioni di programmazione - e io dubito che sarà un grande successo per le prestazioni.


Dal momento che dici hai problemi compilazione di questo, ecco un programma di test che funziona per me in gcc 4.6.1:

#include <stdio.h> 
#define S_2Permute(x) {x[5], x[3], x[4], x[2], x[1]} 

int main(void) { 
    int x[] = {1,2,3,4,5,6}; 
    int y[] = S_2Permute(x); 

    for(int i = 0; i < 5; i++) { 
    printf("%d,",y[i]); 
    } 
    printf("\n"); 
} 

ho compilato con gcc test.c -std=c99 -Wall

+0

Ricevo un errore del compilatore quando provo questo: 'MACRO_TEST.c: 4: 1: errore: previsto '=', ',', ';', 'asm' o '__attribute__' prima di '{' token' –

+0

Really ? Puoi pubblicare la tua macro e la linea su cui la usi? Funziona per me in GCC 4.6.1 –

+0

Ecco la macro: '#define S2_PERMUTE (x) {x [4], x [2], x [3], x [1], x [0]}' E Io chiamo la macro proprio come hai fatto nel tuo esempio. Sto usando gcc 4.5.2. Quando eseguo gcc -E, tuttavia, vedo che il preprocessore ha espanso correttamente l'array. Pubblicherò l'intero programma sopra. –

2

Sono nuovo quindi scuse se non è giusto offrire un mezzo diverso di soluzione ma hai pensato di utilizzare una funzione inline invece di una macro?

amo singole linee di codice che fanno un sacco tanto quanto la persona accanto, ma ha più senso per me a fare in questo modo:

//I would have an array that defined how I wanted to swap the positions, I'll assume 5 elements 
short reordering[5] = {4,1,3,2,0}; 

inline void permuteArray(char array[]) { 
    char swap = array[reordering[0]]; 
    array[reordering[0]] = array[reordinger[1]]; 
    array[reordering[1]] = array[reordinger[2]]; 
    array[reordering[2]] = array[reordinger[3]]; 
    array[reordering[3]] = array[reordinger[4]]; 
    array[reordering[4]] = swap; 
} 

Questo potrebbe non essere così bella o efficienti come una macro, ma potrebbe farti risparmiare qualche mal di testa nella gestione e nella manutenzione del tuo codice (e potrebbe sempre essere scambiato per la versione macro suggerita da Timothy.

+2

È perfettamente corretto suggerire una soluzione diversa (e migliore!) A qualsiasi domanda, purché risolva il problema in questione. Dovresti migliorare la tua risposta elaborando ciò che intendevi per "usare una funzione inline", preferibilmente con esempi di codice compilabili. –

+0

Grazie per la risposta, lo farà. –

+0

Grazie per il suggerimento @RobotRocker. –

0

Sto facendo qualcosa di molto simile Questo è il mio codice. un ulong, quindi lo converto in un array di bit e poi riorganizzo tutti i bit e poi lo riattacco in un momento.

public override ulong Permutation(ulong input, int[] permuation) 
     { 
      byte[] test = BitConverter.GetBytes(input); 
      BitArray test2 = new BitArray(test); 
      BitArray final = new BitArray(test); 
      ulong x = 0; 
      ulong y = 1; 
      for (int i = 0; i < permuation.Length; i++) 
      { 
       final[i] = test2[(permuation[i]-1)]; 
      } 
      for (int i = 0; i < final.Length; i++) 
      { 

       if (final[i] == true) 
       { 
        x += (1 * y); 
       } 
       else 
       { 
        x += (0 * y); 
       } 
       y = y * 2; 
      } 
      return x; 
     }