views:

949

answers:

3

I'm trying to generate random permutations of an 80-character fixed string in C. Much to my dismay, the system I'm working on lacks strfry(). What's the best way for me to generate a random permutation of this string? Since this will be looped over approx. 100,000 times, performance is an issue.

+12  A: 

Just use the Open Source GLIBC implementation, as found by Google Code.

char *
strfry (char *string)
{
  static int init;
  static struct random_data rdata;
  size_t len, i;

  if (!init)
    {
      static int state[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
      rdata.state = NULL;
      __initstate_r (time ((time_t *) NULL), state, 8, &rdata);
      init = 1;
    }

  len = strlen (string);
  for (i = 0; i < len; ++i)
    {
      int32_t j;
      char c;

      __random_r (&rdata, &j);
      j %= len;

      c = string[i];
      string[i] = string[j];
      string[j] = c;
    }

  return string;
}

You might want to change the GLIBC specific data types to something more generic.

This code uses the Fisher-Yates shuffle which is actually quite easy to implement by yourself, and very efficient.

Konrad Rudolph
You might want to change the proprietary word there, else Stallman might go get you with his katana. A proper substitute might be GLIBC specific.
Vinko Vrsalovic
Konrad, you are a gentleman and a scholar! I tried searching Google Code, but I was looking for things like 'randomize a string in c' instead of simply 'strfry'. Thank you!
Max
@Vinko: very true. ;-)
Konrad Rudolph
Am I the only one who thinks that creating and using a re-entrant random-number generator takes a beautiful algorithm and makes it ugly?
Norman Ramsey
I'd like to mention that strfry() is my favorite name for a function. For a while, it was floorf(), but then I found strfry().
Will Mc
A: 

void gcry_randomize (unsigned char *buffer, size_t length, enum gcry_random_level level)

Fill buffer with length random bytes using a random quality as defined by level.

http://www.g10code.com/p-libgcrypt.html

plan9assembler
Aside from being a proprietary function, which I'm afraid I didn't specify I'd like to avoid, this doesn't actually suit my purpose. I'm trying to generate a random permutation of an existing string -- not a random string. The character frequency is important.
Max
A: 

create a 80-line array, put a character and a random number into each line of the array, then sort the array on the random numbers.

Rebuild string from sorted array.