X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Fsimpleprng.c;h=04e7a9f211b7463bb78e532d97d9ec488d2bdd57;hb=fd48f3e498442f0cbff5f3606c7c403d0566150e;hp=684e5de242f4f954e2153830a31699e073f9d5a1;hpb=96f35b20267e8b1a1c846d476f27fcd330e0b018;p=debian%2Famanda diff --git a/common-src/simpleprng.c b/common-src/simpleprng.c index 684e5de..04e7a9f 100644 --- a/common-src/simpleprng.c +++ b/common-src/simpleprng.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005-2008 Zmanda Inc. All Rights Reserved. + * Copyright (c) 2008, 2010 Zmanda, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published @@ -14,7 +14,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - * Contact information: Zmanda Inc, 465 S Mathlida Ave, Suite 300 + * Contact information: Zmanda Inc, 465 S. Mathilda Ave., Suite 300 * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com */ @@ -32,13 +32,22 @@ simpleprng_seed( guint32 seed) { g_assert(seed != 0); - *state = seed; + state->val = seed; + state->count = 0; +} + +guint32 +simpleprng_get_seed( + simpleprng_state_t *state) +{ + return state->val; } guint32 simpleprng_rand( simpleprng_state_t *state) { - return (*state = (A * (*state)) + C); + state->count++; + return (state->val = (A * state->val) + C); } void simpleprng_fill_buffer( @@ -52,6 +61,23 @@ void simpleprng_fill_buffer( } } +static char * +hexstr(guint8 *p, int len) +{ + char *result = NULL; + int i; + + for (i = 0; i < len; i++) { + if (result) + result = newvstrallocf(result, "%s %02x", result, (guint)(*(p++))); + else + result = vstrallocf("[%02x", (guint)(*(p++))); + } + result = newvstrallocf(result, "%s]", result); + + return result; +} + gboolean simpleprng_verify_buffer( simpleprng_state_t *state, gpointer buf, @@ -59,12 +85,24 @@ gboolean simpleprng_verify_buffer( { guint8 *p = buf; while (len--) { + guint64 count = state->count; guint8 expected = simpleprng_rand_byte(state); guint8 got = *p; if (expected != got) { + int remaining = MIN(len, 16); + guint8 expbytes[16] = { expected }; + char *gotstr = hexstr(p, remaining); + char *expstr; + int i; + + for (i = 1; i < remaining; i++) + expbytes[i] = simpleprng_rand_byte(state); + expstr = hexstr(expbytes, remaining); + g_fprintf(stderr, - "random value mismatch in buffer %p, offset %zd: got 0x%02x, expected 0x%02x\n", - buf, (size_t)(p-(guint8*)buf), (int)got, (int)expected); + "random value mismatch at offset %ju: got %s, expected %s\n", + (uintmax_t)count, gotstr, expstr); + g_free(gotstr); return FALSE; } p++;