summaryrefslogtreecommitdiff
path: root/random.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-01-05 11:31:41 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2005-01-05 11:31:41 +0000
commita0be45773ef5ed09059c337f1597e62ba03d1a4b (patch)
tree2b92a738b268f444008c688c12d04f7377cb014e /random.c
parent23409989edec7b345dd23c289f1e0c4fe28fdc4f (diff)
* random.c (limited_big_rand): didn't work if SIZEOF_BDIGITS == 2.
[ruby-dev:25408] * random.c (random_seed): refined. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@7730 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'random.c')
-rw-r--r--random.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/random.c b/random.c
index 4c86b55..b069c1d 100644
--- a/random.c
+++ b/random.c
@@ -215,7 +215,7 @@ rand_init(vseed)
rb_raise(rb_eTypeError, "failed to convert %s into Integer",
rb_obj_classname(vseed));
}
- len = ((len + 3) / 4); /* round up to 32bits */
+ len = (len + 3) / 4; /* number of 32bit words */
buf = ALLOCA_N(long, len); /* allocate longs for init_by_array */
memset(buf, 0, len * sizeof(long));
if (FIXNUM_P(seed)) {
@@ -228,8 +228,8 @@ rand_init(vseed)
int i, j;
for (i = RBIGNUM(seed)->len-1; 0 <= i; i--) {
j = i * SIZEOF_BDIGITS / 4;
-#if SIZEOF_BDIGITS < SIZEOF_LONG
- buf[j] = buf[j] << (SIZEOF_BDIGITS * 8);
+#if SIZEOF_BDIGITS < 4
+ buf[j] <<= SIZEOF_BDIGITS * 8;
#endif
buf[j] |= ((BDIGIT *)RBIGNUM(seed)->digits)[i];
}
@@ -259,23 +259,21 @@ random_seed()
struct timeval tv;
int fd;
struct stat statbuf;
+
+ int seed_len;
BDIGIT *digits;
unsigned long *seed;
NEWOBJ(big, struct RBignum);
OBJSETUP(big, rb_cBignum, T_BIGNUM);
+
+ seed_len = 4 * sizeof(long);
big->sign = 1;
- big->len = sizeof(long) * 8 / SIZEOF_BDIGITS + 1;
+ big->len = seed_len / SIZEOF_BDIGITS + 1;
digits = big->digits = ALLOC_N(BDIGIT, big->len);
seed = (unsigned long *)big->digits;
memset(digits, 0, big->len * SIZEOF_BDIGITS);
- gettimeofday(&tv, 0);
- seed[0] = tv.tv_usec;
- seed[1] = tv.tv_sec;
- seed[2] = getpid() ^ (n++ << 16);
- seed[3] = (unsigned long)&seed;
-
#ifdef S_ISCHR
if ((fd = open("/dev/urandom", O_RDONLY|O_NONBLOCK
#ifdef O_NOCTTY
@@ -286,12 +284,18 @@ random_seed()
#endif
)) >= 0) {
if (fstat(fd, &statbuf) == 0 && S_ISCHR(statbuf.st_mode)) {
- read(fd, &seed[4], 4 * sizeof(*seed));
+ read(fd, seed, seed_len);
}
close(fd);
}
#endif
+ gettimeofday(&tv, 0);
+ seed[0] ^= tv.tv_usec;
+ seed[1] ^= tv.tv_sec;
+ seed[2] ^= getpid() ^ (n++ << 16);
+ seed[3] ^= (unsigned long)&seed;
+
/* set leading-zero-guard if need. */
digits[big->len-1] = digits[big->len-2] <= 1 ? 1 : 0;
@@ -374,11 +378,11 @@ limited_big_rand(struct RBignum *limit)
val = (struct RBignum *)rb_big_clone((VALUE)limit);
val->sign = 1;
#if SIZEOF_BDIGITS == 2
-# define BIG_GET32(big,i) (((BDIGIT *)(big)->digits)[(i)/2] | \
- ((i)/2+1 < (big)->len ? (((BDIGIT *)(big)->digits)[(i)/2+1] << 16)
+# define BIG_GET32(big,i) (((BDIGIT *)(big)->digits)[(i)*2] | \
+ ((i)*2+1 < (big)->len ? (((BDIGIT *)(big)->digits)[(i)*2+1] << 16) \
: 0))
-# define BIG_SET32(big,i,d) ((((BDIGIT *)(big)->digits)[(i)/2] = (d) & 0xffff), \
- ((i)/2+1 < (big)->len ? (((BDIGIT *)(big)->digits)[(i)/2+1] = (d) >> 16) \
+# define BIG_SET32(big,i,d) ((((BDIGIT *)(big)->digits)[(i)*2] = (d) & 0xffff), \
+ ((i)*2+1 < (big)->len ? (((BDIGIT *)(big)->digits)[(i)*2+1] = (d) >> 16) \
: 0))
#else
/* SIZEOF_BDIGITS == 4 */