Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C array permutations with macros

Tags:

c

macros

Is it possible to generate a specific permutation of an array with a macro in C?

i.e. If I have an array X with elements:

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

I was thinking there may be some macro foo for something like this:

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

where I redefine the order of the array, so the element in the original position 5 is now in position 0.

Any ideas?

EXAMPLE USE

I am starting to create an implementation of the DES encryption algorithm. DES requires several permutation/expansions where I would have to re-order all of the elements in the array, sometimes shrinking the array and sometimes expanding it. I was hoping to just be able to define a macro to permute the arrays for me.

EDIT2

Well in DES the first step is something called the initial permutation. So initially I have some 64-bit key, which for this example can be 0-15 hex:

0123456789ABCDEF 

which expands to:

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

The IP (initial permutation) would permute this string so that every element in the array would be in a new position:

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

So the new 1st element in the bitstring would be the 58th element(bit) from the original bitstring.

So I would have all of these bits stored in an array of characters:

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]

and then just call

IP_PERMUTE(x);

And macro magic will have moved all of the bits into the new correct positions.

like image 239
Hunter McMillen Avatar asked Feb 09 '12 02:02

Hunter McMillen


2 Answers

Absolutely - you're almost there with your example. Try this:

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

Then later:

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

Two things to remember:

1) in C, arrays are numbered from 0, so it's possible you meant:

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

2) If you're using gcc, you can compile with -E to see the output from the preprocessor (very good for debugging macro expansions).


However, I don't think I'd actually do it this way - I'd say the code will be easier to read (and potentially less error prone) if you generate the permutations programmatically - and I doubt that it'll be a large performance hit.


Since you say you're having trouble compiling this, here's a test program that works for 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");
}

I compiled with gcc test.c -std=c99 -Wall

like image 122
Timothy Jones Avatar answered Sep 25 '22 06:09

Timothy Jones


I'm new so apologies if it's not ok to offer a different means of solution but have you considered using an inline function instead of a macro?

I love single lines of code that do a lot as much as the next guy, but it makes more sense to me to do it this way:

//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;
}

This may not be as pretty or efficient as a macro, but it could save you some headaches managing and maintaining your code (and could always be swapped for the macro version Timothy suggest.

like image 40
Robot Rocker Avatar answered Sep 22 '22 06:09

Robot Rocker