79 lines
1.8 KiB
C
79 lines
1.8 KiB
C
#include "badrand.h"
|
|
#include "stdio.h"
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#define PRAND_BUILD_SEED \
|
|
((uint64_t)(__TIME__[0]) * (uint64_t)(__TIME__[1]) * (uint64_t)(__TIME__[3]) * (uint64_t)(__TIME__[4]) * \
|
|
(uint64_t)(__TIME__[6]) * (uint64_t)(__TIME__[7]))
|
|
|
|
static uint64_t seed = PRAND_BUILD_SEED * 6364136223846793005ULL + 1;
|
|
|
|
uint64_t badrand() {
|
|
seed = seed * 6364136223846793005ULL + 1;
|
|
return seed;
|
|
}
|
|
|
|
uint64_t badrand_range(uint64_t min, uint64_t max) {
|
|
uint64_t range = max - min + 1;
|
|
uint64_t x;
|
|
uint64_t limit = UINT64_MAX - (UINT64_MAX % range);
|
|
|
|
do {
|
|
x = badrand();
|
|
} while (x > limit);
|
|
|
|
return min + (x % range);
|
|
}
|
|
|
|
void badrand_buf(char *buf, size_t len) {
|
|
unsigned char *p = (unsigned char *)buf;
|
|
|
|
while (len >= 8) {
|
|
uint64_t r = badrand();
|
|
memcpy(p, &r, 8);
|
|
p += 8;
|
|
len -= 8;
|
|
}
|
|
|
|
if (len > 0) {
|
|
uint64_t r = badrand();
|
|
memcpy(p, &r, len);
|
|
}
|
|
}
|
|
|
|
void sbadrand(uint64_t s) {
|
|
if (s) {
|
|
seed ^= (s * 0x9e3779b97f4a7c15ULL) + (seed << 6) + (seed >> 2);
|
|
} else {
|
|
seed ^= PRAND_BUILD_SEED;
|
|
}
|
|
}
|
|
|
|
/* Simple but dumb sanity check for randomness */
|
|
int looks_random(char *buf, size_t len) {
|
|
int counts[256] = {0};
|
|
int run = 1, max_run = 1;
|
|
|
|
for (size_t i = 0; i < len; i++) {
|
|
counts[(unsigned int)buf[i]]++;
|
|
if (i > 0 && buf[i] == buf[i - 1]) {
|
|
if (++run > max_run)
|
|
max_run = run;
|
|
} else {
|
|
run = 1;
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < 256; i++) {
|
|
if (counts[i] > (int)(len * 1 / 10))
|
|
return 0;
|
|
}
|
|
|
|
if (max_run > 16)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
#undef PRAND_BUILD_SEED
|