13

Is there a library function that creates a random string in the same way that mkstemp() creates a unique file name? What is it?

nbro
  • 15,395
  • 32
  • 113
  • 196
cody
  • 651
  • 2
  • 8
  • 16
  • 6
    There is no standard function for this, but it is straightforward to write one. EG: http://stackoverflow.com/questions/440133/how-do-i-create-a-random-alpha-numeric-string-in-c – Justin Ethier Apr 02 '13 at 15:12
  • 1
    There is as far as I am aware no function to do this in the standard C library. However this has been asked numerous times before: http://stackoverflow.com/search?q=%5Bc%5Dcreate+random+string – devrobf Apr 02 '13 at 15:13

2 Answers2

21

There's no standard function, but your OS might implement something. Have you considered searching through the manuals? Alternatively, this task is simple enough. I'd be tempted to use something like:

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

void rand_str(char *, size_t);

int main(void) {
    char str[] = { [41] = '\1' }; // make the last character non-zero so we can test based on it later
    rand_str(str, sizeof str - 1);
    assert(str[41] == '\0');      // test the correct insertion of string terminator
    puts(str);
}

void rand_str(char *dest, size_t length) {
    char charset[] = "0123456789"
                     "abcdefghijklmnopqrstuvwxyz"
                     "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

    while (length-- > 0) {
        size_t index = (double) rand() / RAND_MAX * (sizeof charset - 1);
        *dest++ = charset[index];
    }
    *dest = '\0';
}

This has the neat benefit of working correctly on EBCDIC systems, and being able to accommodate virtually any character set. I haven't added any of the following characters into the character set, because it seems clear that you want strings that could be filenames:

":;?@[\]^_`{|}"

I figured many of those characters could be invalid in filenames on various OSes.

autistic
  • 1
  • 3
  • 35
  • 80
  • 1
    This always produces the same output compiled and run on my Mac unless I make these tweaks: in the includes section: `#include ` .. just before everything else in `main`: `srand((unsigned int)(time(NULL)));` (Seeds random with time) – Alex Hall Feb 27 '20 at 00:33
  • Why not `index = rand() % ( sizeof charset - 1 );`? – pmor Sep 26 '20 at 20:14
  • @pmor because I researched [how to use `rand` properly](http://www.azillionmonkeys.com/qed/random.html) and determined the pattern you suggested to be subtly erroneous. – autistic May 05 '21 at 23:21
3

There's no build in API, you may use (on *x system) /dev/urandom like:

FILE *f = fopen( "/dev/urandom", "r");
if( !f) ...
fread( binary_string, string_length, f);
fclose(f);

Note that this will create binary data, not string data so you'll may have to filter it afterwards.

You may also use standard pseudorandom generator rand():

#include <time.h>
#include <stdlib.h>

// In main:
srand(time(NULL));
for( int i = 0; i < string_length; ++i){
    string[i] = '0' + rand()%72; // starting on '0', ending on '}'
}

And if you need really random string you need to google generating random sequence cryptography which is one of cryptography's difficult problems which still hasn't perfect solution :)

Vyktor
  • 20,559
  • 6
  • 64
  • 96
  • Which characters do you suppose might be in this random string if EBCDIC is used as the character set? – autistic Apr 02 '13 at 15:22
  • @modifiablelvalue somehow I assumed ASCII... And to be honest I didn't meant the answer as full "give me teh codes" but rather as an inspiration. – Vyktor Apr 02 '13 at 15:28