3
\$\begingroup\$

It is just a simple piece of C code that generates random lenght random HEX srings. Any ideas how this code can be improved?

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

#define MAX_SIZE 256

int main() {
    time_t t;
    srand((unsigned) time(&t));

    const char* digits = "0123456789ABCDEF";

    unsigned char str_len = rand() % MAX_SIZE;


    char* str = malloc((str_len + 1) * sizeof(char));
    if (str == NULL) {
        fprintf(stderr, "malloc failed\n");
        return -1;
    }

    char* init_ptr = str;
    char tmp_char;

    for (int i = 0; i < str_len; i++) {
        if (i == 0) {
            do {
                tmp_char = *(digits + (rand() % 16));
            } while (tmp_char == '0');
        }
        *str = tmp_char;
        tmp_char = *(digits + (rand() % 16));
        str++;
    }

    *str = '\0';

    printf("%s", init_ptr);
    free(init_ptr);

    return 0;
}
\$\endgroup\$

3 Answers 3

1
\$\begingroup\$

You are effectively picking your first hex digit from "123456789ABCDEF" (no zero) and the subsequent digits from "0123456789ABCDEF". Hence it might be better to adjust the first random pick:

// This assumes that str_len is at least 1.
*str = *(digits + (1 + rand() % 15));  // Pick first char in range 1..15
str++;

// For loop starts at 1 as str[0] already picked.
for (int i = 1; i < str_len; i++) {
    *str = *(digits + (rand() % 16));  // Following chars in range 0..15
    str++;
}

That eliminates the tmp_char variable and the while loop, which makes the code a lot cleaner, to my eye anyway.

\$\endgroup\$
0
\$\begingroup\$

Looks pretty good although I think the if statement inside the for loop is redundant, i is always going to be 0 initially so you can just go straight into the do{} while()

\$\endgroup\$
1
  • \$\begingroup\$ It is just used to protect result from first '0'. If remove it, there won't be zeros in other positions. \$\endgroup\$
    – bfrogg
    Commented Dec 9, 2016 at 7:07
0
\$\begingroup\$

Your do/while loop is redundant. You can simply generate a smaller random number and increment by 1:

tmp_char = *(digits + (rand() % 15) + 1);

Using malloc for this also seems like overkill. I'd simply declare a char array of size MAX_SIZE. The buffer is only used locally to the main function and is relatively small so can be declared safely on the stack.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.