X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/puzzles/blobdiff_plain/7959b51735be301d234b41ac2f3b88bdcc34a34a..a8c8847b94f2f07c350a331dfcbedbebef5b5c82:/random.c diff --git a/random.c b/random.c index d70dd00..107649c 100644 --- a/random.c +++ b/random.c @@ -12,6 +12,7 @@ #include #include +#include #include "puzzles.h" @@ -263,7 +264,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 +279,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; +}