X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/7959b51735be301d234b41ac2f3b88bdcc34a34a..HEAD:/random.c diff --git a/random.c b/random.c index d70dd00..6d278a4 100644 --- a/random.c +++ b/random.c @@ -12,6 +12,7 @@ #include #include +#include #include "puzzles.h" @@ -206,7 +207,7 @@ struct random_state { int pos; }; -random_state *random_init(char *seed, int len) +random_state *random_new(char *seed, int len) { random_state *state; @@ -220,6 +221,16 @@ random_state *random_init(char *seed, int len) return state; } +random_state *random_copy(random_state *tocopy) +{ + random_state *result; + result = snew(random_state); + memcpy(result->seedbuf, tocopy->seedbuf, sizeof(result->seedbuf)); + memcpy(result->databuf, tocopy->databuf, sizeof(result->databuf)); + result->pos = tocopy->pos; + return result; +} + unsigned long random_bits(random_state *state, int bits) { unsigned long ret = 0; @@ -263,7 +274,7 @@ unsigned long random_upto(random_state *state, unsigned long limit) bits += 3; assert(bits < 32); - max = 1 << bits; + max = 1L << bits; divisor = max / limit; max = limit * divisor; @@ -278,3 +289,63 @@ void random_free(random_state *state) { sfree(state); } + +char *random_state_encode(random_state *state) +{ + char retbuf[256]; + int len = 0, i; + + for (i = 0; i < lenof(state->seedbuf); i++) + len += sprintf(retbuf+len, "%02x", state->seedbuf[i]); + for (i = 0; i < lenof(state->databuf); i++) + len += sprintf(retbuf+len, "%02x", state->databuf[i]); + len += sprintf(retbuf+len, "%02x", state->pos); + + return dupstr(retbuf); +} + +random_state *random_state_decode(char *input) +{ + random_state *state; + int pos, byte, digits; + + state = snew(random_state); + + memset(state->seedbuf, 0, sizeof(state->seedbuf)); + memset(state->databuf, 0, sizeof(state->databuf)); + state->pos = 0; + + byte = digits = 0; + pos = 0; + while (*input) { + int v = *input++; + + if (v >= '0' && v <= '9') + v = v - '0'; + else if (v >= 'A' && v <= 'F') + v = v - 'A' + 10; + else if (v >= 'a' && v <= 'f') + v = v - 'a' + 10; + else + v = 0; + + byte = (byte << 4) | v; + digits++; + + if (digits == 2) { + /* + * We have a byte. Put it somewhere. + */ + if (pos < lenof(state->seedbuf)) + state->seedbuf[pos++] = byte; + else if (pos < lenof(state->seedbuf) + lenof(state->databuf)) + state->databuf[pos++ - lenof(state->seedbuf)] = byte; + else if (pos == lenof(state->seedbuf) + lenof(state->databuf) && + byte <= lenof(state->databuf)) + state->pos = byte; + byte = digits = 0; + } + } + + return state; +}