char *genStr(char *filename, int len) { int fh; unsigned char *data; if ((fh = open(filename, O_RDONLY)) == -1) FILE_ERR(filename, "open"); struct stat finfo; fstat(fh, &finfo); if ((data = mmap(0, finfo.st_size, PROT_READ, MAP_SHARED, fh, 0)) == MAP_FAILED) FILE_ERR(filename, "mmap"); if (close(fh) == -1) FILE_ERR(filename, "close"); int dataIdx = 0, alphabetSize = 1; for (; data[dataIdx]; dataIdx += byteLength(data[dataIdx]), ++alphabetSize); ++dataIdx; // we're on the null byte, want to be where data actually starts if (alphabetSize*alphabetSize*(8+4*alphabetSize) != finfo.st_size - dataIdx) { return "!!! CORRUPT DATA FILE !!!"; } char *str = malloc((len+1) * 4*sizeof *str); int a = alphabetSize - 1, b = alphabetSize - 1; int strpos = 0; for (int i = 0; i < len; ++i) { unsigned char *dataPtr = DATA(a, b); unsigned long long n = longRand(getLong(dataPtr)); dataPtr += 8; int nextCharPos = 0; for (; nextCharPos < alphabetSize; ++nextCharPos) { unsigned int m = getInt(dataPtr); if (m > n) break; n -= m; dataPtr += 4; } a = b; b = nextCharPos; int alphabetIdx = 0; for (; nextCharPos; --nextCharPos) { alphabetIdx += byteLength(ALPHABET[alphabetIdx]); } int nextCharLen = byteLength(ALPHABET[alphabetIdx]); for (int i = nextCharLen; i >= 0; --i) { str[strpos + i] = ALPHABET[alphabetIdx + i]; } strpos += nextCharLen; } str[strpos] = '\0'; //for (int i = 0; i < len*2; ++i) printf("str[%d]: %c\n", i, str[i]); if (munmap(data, finfo.st_size) == -1) FILE_ERR(filename, "munmap"); return str; }
long selectBetween( long lo, long hi ) { long r; r = longRand(); return ( r % ( hi - lo + 1 ) + lo ); }