Monday, April 2, 2012

Create random strings, shuffle existing strings

Create random strings, shuffle existing strings

#include <time.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include <stdlib.h>
#include <stddef.h>
#include <limits.h>

#define PACKAGE "strang"
#define VERSION "1.0.0"

void print_help(int exval);
int get_rand_val(int low, int high);
char *get_rand_str(int length);
char *strshuf(char *str);
unsigned time_seed(void);

int main(int argc, char *argv[]) {
 char *str = NULL;
 char *affix = NULL;
 char *prefix = NULL;
 int opt = 0;
 int len = 0;
 int number = 1;

 while((opt = getopt(argc, argv, "hvn:l:p:a:s:")) != -1) {
  switch(opt) {
   case 'h':
    print_help(0);
    break;
   case 'v':
    fprintf(stdout, "%s %s\n", PACKAGE, VERSION);
    exit(0);
    break;
   case 'n':
    number = atoi(optarg);
    break;
   case 'l': /* string length (default=random) */
    len = atoi(optarg);
    break;
   case 'p': /* prefix string with STR */
    prefix = strdup(optarg);
    break;
   case 'a': /* affix string with STR */
    affix = strdup(optarg);
    break;
   case 's': /* randomize string STR */
    str = strdup(optarg);  
    break;
   case ':':
    fprintf(stderr, "%s: Error - Option `%c', needs an argument\n\n", PACKAGE, optopt);
    print_help(1);
    break;
   case '?':
    fprintf(stderr, "%s: Error - No such option: `%c'\n\n", PACKAGE, optopt);
    print_help(1);
    break;
  } /* switch */
 } /* while */

 /* ! definitely not cryptographic secure ! */
 srand((time_seed()));

 for(; number > 0; number--) {
  if(prefix != NULL)
   printf("%s", prefix);

  if(str != NULL)
   printf("%s", strshuf(str));
  else {
   if(len != 0)
    printf("%s", get_rand_str(len));
   else
    printf("%s", get_rand_str(get_rand_val(1, 20)));
  }

  if(affix != NULL)
   printf("%s", affix);

  printf("\n");
 } /* for */

 return 0;
}

char *strshuf(char *str) {
 int pick = 0;
 int len = 0;
 int i = 0;
 char tmp;
 char *retval = NULL;

 /* strip trailing newline */
 if(str[strlen(str) - 1] == '\n')
  str[strlen(str) - 1] = '\0';

 len = strlen(str) - 1;

 for(i = 0; i < len; i++) {
  /* pick a random char out of input string */
  pick = get_rand_val(1, len);
  /* swap orig char with pick */
  tmp = str[i];
  str[i] = str[pick];
  str[pick] = tmp;
 }

 retval = calloc(strlen(str) + 1, sizeof(char));
 strcpy(retval, str);

 return retval;
 free(retval);
}

char *get_rand_str(int length) {
 int value = 0;
 char temp[1];
 char *retval = NULL;

 if((retval = calloc(length + 1, sizeof(char))) == NULL) {
  fprintf(stderr, "%s: Error - calloc\n\n", PACKAGE);
  return NULL;
 }

 for(; length > 0; length--) {
  value = get_rand_val(97, 122);
  temp[0] = value, temp[1] = '\0';
  strcat(retval, temp);
 }

 return retval;
 free(retval);
}

int get_rand_val(int low, int high) {
 int k = 0;
 double d = 0;

 d = (double)rand() / ((double)RAND_MAX + 1);
 k = (int)(d * (high - low + 1));

 return(low + k);
}

/* ! definitely not cryptographic secure ! */
unsigned time_seed(void) {
 int retval;
 int fd;

 if(open("/dev/urandom", O_RDONLY) == -1) {
  retval = (((int)time(NULL)) & ((1 << 30) - 1)) + getpid();
 } else {
  read(fd, &retval, 4);
  /* positive values only */
  retval = abs(retval) + getpid();
  close(fd);
 }

 return retval;
}

void print_help(int exval) {
 printf("%s,%s generate random strings - shuffle existing strings\n", PACKAGE, VERSION);
 printf("Usage: %s [-h] [-v] [-n INT] [-l INT] [-p STR] [-a STR] [-s STR]\n\n", PACKAGE);

 printf(" Default:\n");
 printf("  -h         print this help and exit\n");
 printf("  -v         print version and exit\n\n");

 printf(" Random:\n");
 printf("  -n INT     output number of strings, (default=1)\n");
 printf("  -l INT     string length, (default=random `1-10')\n");
 printf("  -p STR     prefix string with STR\n");
 printf("  -a STR     affix string with STR\n");
 printf("  -s STR     randomize string STR\n\n");


 printf(" example : %s -s 'abcdef'\n", PACKAGE);
 printf(" output  : fceabd\n\n");

 exit(exval);
}

No comments:

Post a Comment