crypt-isaac 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +46 -4
- data/Rakefile +9 -0
- data/crypt-isaac.gemspec +3 -2
- data/ext/crypt/isaac/Makefile +260 -0
- data/ext/crypt/isaac/extconf.rb +3 -0
- data/ext/crypt/isaac/isaac.c +232 -0
- data/ext/crypt/isaac/rand.c +142 -0
- data/ext/crypt/isaac/rand.h +56 -0
- data/ext/crypt/isaac/standard.h +57 -0
- data/ext/crypt/isaac/xorshift/extconf.rb +3 -0
- data/ext/crypt/isaac/xorshift/xorshift.c +121 -0
- data/lib/crypt/isaac.rb +14 -211
- data/lib/crypt/isaac/pure.rb +218 -0
- data/lib/crypt/isaac/version.rb +1 -1
- data/lib/crypt/isaac/xorshift.rb +5 -0
- data/lib/crypt/isaac/xorshift/pure.rb +47 -0
- metadata +23 -7
@@ -0,0 +1,142 @@
|
|
1
|
+
/*
|
2
|
+
------------------------------------------------------------------------------
|
3
|
+
rand.c: By Bob Jenkins. My random number generator, ISAAC. Public Domain
|
4
|
+
MODIFIED:
|
5
|
+
960327: Creation (addition of randinit, really)
|
6
|
+
970719: use context, not global variables, for internal state
|
7
|
+
980324: make a portable version
|
8
|
+
010626: Note this is public domain
|
9
|
+
100725: Mask on use of >32 bits, not on assignment: from Paul Eggert
|
10
|
+
------------------------------------------------------------------------------
|
11
|
+
*/
|
12
|
+
#ifndef STANDARD
|
13
|
+
#include "standard.h"
|
14
|
+
#endif
|
15
|
+
#ifndef RAND
|
16
|
+
#include "rand.h"
|
17
|
+
#endif
|
18
|
+
|
19
|
+
|
20
|
+
#define ind(mm,x) ((mm)[(x>>2)&(RANDSIZ-1)])
|
21
|
+
#define rngstep(mix,a,b,mm,m,m2,r,x) \
|
22
|
+
{ \
|
23
|
+
x = *m; \
|
24
|
+
a = ((a^(mix)) + *(m2++)); \
|
25
|
+
*(m++) = y = (ind(mm,x) + a + b); \
|
26
|
+
*(r++) = b = (ind(mm,y>>RANDSIZL) + x) & 0xffffffff; \
|
27
|
+
}
|
28
|
+
|
29
|
+
void isaac(ctx)
|
30
|
+
randctx *ctx;
|
31
|
+
{
|
32
|
+
ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
|
33
|
+
mm=ctx->randmem; r=ctx->randrsl;
|
34
|
+
a = ctx->randa; b = ctx->randb + (++ctx->randc);
|
35
|
+
for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
|
36
|
+
{
|
37
|
+
rngstep( a<<13, a, b, mm, m, m2, r, x);
|
38
|
+
rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x);
|
39
|
+
rngstep( a<<2 , a, b, mm, m, m2, r, x);
|
40
|
+
rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x);
|
41
|
+
}
|
42
|
+
for (m2 = mm; m2<mend; )
|
43
|
+
{
|
44
|
+
rngstep( a<<13, a, b, mm, m, m2, r, x);
|
45
|
+
rngstep( (a & 0xffffffff) >>6 , a, b, mm, m, m2, r, x);
|
46
|
+
rngstep( a<<2 , a, b, mm, m, m2, r, x);
|
47
|
+
rngstep( (a & 0xffffffff) >>16, a, b, mm, m, m2, r, x);
|
48
|
+
}
|
49
|
+
ctx->randb = b; ctx->randa = a;
|
50
|
+
}
|
51
|
+
|
52
|
+
|
53
|
+
#define mix(a,b,c,d,e,f,g,h) \
|
54
|
+
{ \
|
55
|
+
a^=b<<11; d+=a; b+=c; \
|
56
|
+
b^=(c&0xffffffff)>>2; e+=b; c+=d; \
|
57
|
+
c^=d<<8; f+=c; d+=e; \
|
58
|
+
d^=(e&0xffffffff)>>16; g+=d; e+=f; \
|
59
|
+
e^=f<<10; h+=e; f+=g; \
|
60
|
+
f^=(g&0xffffffff)>>4; a+=f; g+=h; \
|
61
|
+
g^=h<<8; b+=g; h+=a; \
|
62
|
+
h^=(a&0xffffffff)>>9; c+=h; a+=b; \
|
63
|
+
}
|
64
|
+
|
65
|
+
/* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
|
66
|
+
void randinit(ctx, flag)
|
67
|
+
randctx *ctx;
|
68
|
+
word flag;
|
69
|
+
{
|
70
|
+
word i;
|
71
|
+
ub4 a,b,c,d,e,f,g,h;
|
72
|
+
ub4 *m,*r;
|
73
|
+
ctx->randa = ctx->randb = ctx->randc = 0;
|
74
|
+
m=ctx->randmem;
|
75
|
+
r=ctx->randrsl;
|
76
|
+
a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
|
77
|
+
|
78
|
+
for (i=0; i<4; ++i) /* scramble it */
|
79
|
+
{
|
80
|
+
mix(a,b,c,d,e,f,g,h);
|
81
|
+
}
|
82
|
+
|
83
|
+
if (flag)
|
84
|
+
{
|
85
|
+
/* initialize using the contents of r[] as the seed */
|
86
|
+
for (i=0; i<RANDSIZ; i+=8)
|
87
|
+
{
|
88
|
+
a+=r[i ]; b+=r[i+1];
|
89
|
+
c+=r[i+2]; d+=r[i+3];
|
90
|
+
e+=r[i+4]; f+=r[i+5];
|
91
|
+
g+=r[i+6]; h+=r[i+7];
|
92
|
+
mix(a,b,c,d,e,f,g,h);
|
93
|
+
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
94
|
+
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
95
|
+
}
|
96
|
+
/* do a second pass to make all of the seed affect all of m */
|
97
|
+
for (i=0; i<RANDSIZ; i+=8)
|
98
|
+
{
|
99
|
+
a+=m[i ]; b+=m[i+1];
|
100
|
+
c+=m[i+2]; d+=m[i+3];
|
101
|
+
e+=m[i+4]; f+=m[i+5];
|
102
|
+
g+=m[i+6]; h+=m[i+7];
|
103
|
+
mix(a,b,c,d,e,f,g,h);
|
104
|
+
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
105
|
+
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
else
|
109
|
+
{
|
110
|
+
for (i=0; i<RANDSIZ; i+=8)
|
111
|
+
{
|
112
|
+
/* fill in mm[] with messy stuff */
|
113
|
+
mix(a,b,c,d,e,f,g,h);
|
114
|
+
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
115
|
+
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
isaac(ctx); /* fill in the first set of results */
|
120
|
+
ctx->randcnt=RANDSIZ; /* prepare to use the first set of results */
|
121
|
+
}
|
122
|
+
|
123
|
+
|
124
|
+
#ifdef NEVER
|
125
|
+
int main()
|
126
|
+
{
|
127
|
+
ub4 i,j;
|
128
|
+
randctx ctx;
|
129
|
+
ctx.randa=ctx.randb=ctx.randc=(ub4)0;
|
130
|
+
for (i=0; i<256; ++i) ctx.randrsl[i]=(ub4)0;
|
131
|
+
randinit(&ctx, TRUE);
|
132
|
+
for (i=0; i<2; ++i)
|
133
|
+
{
|
134
|
+
isaac(&ctx);
|
135
|
+
for (j=0; j<256; ++j)
|
136
|
+
{
|
137
|
+
printf("%.8lx",ctx.randrsl[j]);
|
138
|
+
if ((j&7)==7) printf("\n");
|
139
|
+
}
|
140
|
+
}
|
141
|
+
}
|
142
|
+
#endif
|
@@ -0,0 +1,56 @@
|
|
1
|
+
/*
|
2
|
+
------------------------------------------------------------------------------
|
3
|
+
rand.h: definitions for a random number generator
|
4
|
+
By Bob Jenkins, 1996, Public Domain
|
5
|
+
MODIFIED:
|
6
|
+
960327: Creation (addition of randinit, really)
|
7
|
+
970719: use context, not global variables, for internal state
|
8
|
+
980324: renamed seed to flag
|
9
|
+
980605: recommend RANDSIZL=4 for noncryptography.
|
10
|
+
010626: note this is public domain
|
11
|
+
------------------------------------------------------------------------------
|
12
|
+
*/
|
13
|
+
#ifndef STANDARD
|
14
|
+
#include "standard.h"
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#ifndef RAND
|
18
|
+
#define RAND
|
19
|
+
#define RANDSIZL (8)
|
20
|
+
#define RANDSIZ (1<<RANDSIZL)
|
21
|
+
|
22
|
+
/* context of random number generator */
|
23
|
+
struct randctx
|
24
|
+
{
|
25
|
+
ub4 randcnt;
|
26
|
+
ub4 randrsl[RANDSIZ];
|
27
|
+
ub4 randmem[RANDSIZ];
|
28
|
+
ub4 randa;
|
29
|
+
ub4 randb;
|
30
|
+
ub4 randc;
|
31
|
+
};
|
32
|
+
typedef struct randctx randctx;
|
33
|
+
|
34
|
+
/*
|
35
|
+
------------------------------------------------------------------------------
|
36
|
+
If (flag==TRUE), then use the contents of randrsl[0..RANDSIZ-1] as the seed.
|
37
|
+
------------------------------------------------------------------------------
|
38
|
+
*/
|
39
|
+
void randinit( randctx *r, word flag );
|
40
|
+
|
41
|
+
void isaac( randctx *r );
|
42
|
+
|
43
|
+
|
44
|
+
/*
|
45
|
+
------------------------------------------------------------------------------
|
46
|
+
Call rand(/o_ randctx *r _o/) to retrieve a single 32-bit random value
|
47
|
+
------------------------------------------------------------------------------
|
48
|
+
*/
|
49
|
+
#define rand(r) \
|
50
|
+
(!(r)->randcnt-- ? \
|
51
|
+
(isaac(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \
|
52
|
+
(r)->randrsl[(r)->randcnt])
|
53
|
+
|
54
|
+
#endif /* RAND */
|
55
|
+
|
56
|
+
|
@@ -0,0 +1,57 @@
|
|
1
|
+
/*
|
2
|
+
------------------------------------------------------------------------------
|
3
|
+
Standard definitions and types, Bob Jenkins
|
4
|
+
------------------------------------------------------------------------------
|
5
|
+
*/
|
6
|
+
#ifndef STANDARD
|
7
|
+
# define STANDARD
|
8
|
+
# ifndef STDIO
|
9
|
+
# include <stdio.h>
|
10
|
+
# define STDIO
|
11
|
+
# endif
|
12
|
+
# ifndef STDDEF
|
13
|
+
# include <stddef.h>
|
14
|
+
# define STDDEF
|
15
|
+
# endif
|
16
|
+
typedef unsigned long long ub8;
|
17
|
+
#define UB8MAXVAL 0xffffffffffffffffLL
|
18
|
+
#define UB8BITS 64
|
19
|
+
typedef signed long long sb8;
|
20
|
+
#define SB8MAXVAL 0x7fffffffffffffffLL
|
21
|
+
typedef unsigned long int ub4; /* unsigned 4-byte quantities */
|
22
|
+
#define UB4MAXVAL 0xffffffff
|
23
|
+
typedef signed long int sb4;
|
24
|
+
#define UB4BITS 32
|
25
|
+
#define SB4MAXVAL 0x7fffffff
|
26
|
+
typedef unsigned short int ub2;
|
27
|
+
#define UB2MAXVAL 0xffff
|
28
|
+
#define UB2BITS 16
|
29
|
+
typedef signed short int sb2;
|
30
|
+
#define SB2MAXVAL 0x7fff
|
31
|
+
typedef unsigned char ub1;
|
32
|
+
#define UB1MAXVAL 0xff
|
33
|
+
#define UB1BITS 8
|
34
|
+
typedef signed char sb1; /* signed 1-byte quantities */
|
35
|
+
#define SB1MAXVAL 0x7f
|
36
|
+
typedef int word; /* fastest type available */
|
37
|
+
|
38
|
+
#define bis(target,mask) ((target) |= (mask))
|
39
|
+
#define bic(target,mask) ((target) &= ~(mask))
|
40
|
+
#define bit(target,mask) ((target) & (mask))
|
41
|
+
#ifndef min
|
42
|
+
# define min(a,b) (((a)<(b)) ? (a) : (b))
|
43
|
+
#endif /* min */
|
44
|
+
#ifndef max
|
45
|
+
# define max(a,b) (((a)<(b)) ? (b) : (a))
|
46
|
+
#endif /* max */
|
47
|
+
#ifndef align
|
48
|
+
# define align(a) (((ub4)a+(sizeof(void *)-1))&(~(sizeof(void *)-1)))
|
49
|
+
#endif /* align */
|
50
|
+
#ifndef abs
|
51
|
+
# define abs(a) (((a)>0) ? (a) : -(a))
|
52
|
+
#endif
|
53
|
+
#define TRUE 1
|
54
|
+
#define FALSE 0
|
55
|
+
#define SUCCESS 0 /* 1 on VAX */
|
56
|
+
|
57
|
+
#endif /* STANDARD */
|
@@ -0,0 +1,121 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include <sys/types.h>
|
3
|
+
#include <unistd.h>
|
4
|
+
|
5
|
+
static VALUE CryptModule;
|
6
|
+
static VALUE Xorshift64StarClass;
|
7
|
+
static int16_t seed_counter = 0;
|
8
|
+
|
9
|
+
static void Xorshift64Star_free( uint64_t* seed ) {
|
10
|
+
if ( seed ) {
|
11
|
+
xfree( seed );
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
static VALUE Xorshift64Star_alloc( VALUE klass ) {
|
16
|
+
uint64_t* seed;
|
17
|
+
|
18
|
+
return Data_Make_Struct( klass, uint64_t, NULL, Xorshift64Star_free, seed );
|
19
|
+
}
|
20
|
+
|
21
|
+
static VALUE Xorshift64Star_initialize( VALUE self, VALUE args ) {
|
22
|
+
VALUE _seed ;
|
23
|
+
long len = RARRAY_LEN( args );
|
24
|
+
|
25
|
+
if ( len == 0 ) {
|
26
|
+
_seed = rb_funcall( self, rb_intern( "srand" ), 0 );
|
27
|
+
} else {
|
28
|
+
_seed = rb_funcall( self, rb_intern( "srand" ), 1, rb_ary_entry( args, 0 ) );
|
29
|
+
}
|
30
|
+
|
31
|
+
_seed = rb_funcall( self, rb_intern( "srand" ), 1, _seed );
|
32
|
+
rb_iv_set( self, "@old_seed", _seed );
|
33
|
+
return _seed;
|
34
|
+
}
|
35
|
+
|
36
|
+
static VALUE to_hex_block( VALUE arg, VALUE data, int argc, VALUE* argv ) {
|
37
|
+
return rb_funcall( arg, rb_intern( "to_s" ), 1, INT2FIX( 16 ) );
|
38
|
+
}
|
39
|
+
|
40
|
+
static VALUE Xorshift64Star_new_seed( VALUE self ) {
|
41
|
+
VALUE now;
|
42
|
+
VALUE ary;
|
43
|
+
now = rb_funcall( rb_cTime, rb_intern( "now" ), 0 );
|
44
|
+
ary = rb_ary_new();
|
45
|
+
seed_counter++;
|
46
|
+
|
47
|
+
rb_ary_push( ary, rb_funcall( rb_funcall( now, rb_intern( "usec" ), 0 ), rb_intern( "%" ), 1, INT2FIX( 65536 ) ) );
|
48
|
+
rb_ary_push( ary, rb_funcall( rb_funcall( now, rb_intern( "to_i" ), 0 ), rb_intern( "%" ), 1, INT2FIX( 65536 ) ) );
|
49
|
+
rb_ary_push( ary, rb_funcall( INT2FIX( getpid() ), rb_intern( "%" ), 1, INT2FIX( 65536 ) ) );
|
50
|
+
rb_ary_push( ary, INT2FIX( seed_counter ) );
|
51
|
+
return rb_funcall( rb_funcall(
|
52
|
+
rb_block_call( ary, rb_intern( "collect" ), 0, 0, to_hex_block, Qnil ),
|
53
|
+
rb_intern( "join" ),
|
54
|
+
0
|
55
|
+
), rb_intern( "to_i" ), 1, INT2FIX( 16 ) );
|
56
|
+
}
|
57
|
+
|
58
|
+
static VALUE Xorshift64Star_srand( VALUE self, VALUE args ) {
|
59
|
+
uint64_t *seed;
|
60
|
+
long len = RARRAY_LEN( args );
|
61
|
+
VALUE _seed ;
|
62
|
+
|
63
|
+
Data_Get_Struct( self, uint64_t, seed);
|
64
|
+
|
65
|
+
if ( ( len == 0 ) || ( ( len == 1 ) && ( rb_ary_entry( args, 0 ) == Qnil ) ) ) {
|
66
|
+
_seed = rb_funcall( self, rb_intern( "new_seed" ), 0 );
|
67
|
+
} else {
|
68
|
+
_seed = rb_ary_entry( args, 0 );
|
69
|
+
}
|
70
|
+
|
71
|
+
rb_iv_set( self, "@old_seed", ULL2NUM( (*seed) ) );
|
72
|
+
|
73
|
+
(*seed) = NUM2ULL(_seed);
|
74
|
+
return _seed;
|
75
|
+
}
|
76
|
+
|
77
|
+
static VALUE Xorshift64Star_rand( VALUE self, VALUE args ) {
|
78
|
+
long len = RARRAY_LEN( args );
|
79
|
+
uint64_t *seed;
|
80
|
+
uint64_t limit;
|
81
|
+
uint64_t random;
|
82
|
+
Data_Get_Struct( self, uint64_t, seed );
|
83
|
+
|
84
|
+
if ( len == 0 ) {
|
85
|
+
limit = 0;
|
86
|
+
} else {
|
87
|
+
limit = NUM2ULL( rb_ary_entry( args, 0 ) );
|
88
|
+
}
|
89
|
+
|
90
|
+
*seed ^= *seed >> 12;
|
91
|
+
*seed ^= *seed << 25;
|
92
|
+
*seed ^= *seed >> 27;
|
93
|
+
random = *seed * UINT64_C(2685821657736338717);
|
94
|
+
|
95
|
+
if ( limit == 0 ) {
|
96
|
+
return DBL2NUM( (double)( random / 2 ) / 9223372036854775807 );
|
97
|
+
} else {
|
98
|
+
return ULL2NUM( random % limit );
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
static VALUE Xorshift64Star_seed(VALUE self) {
|
103
|
+
return rb_iv_get( self, "@old_seed" );
|
104
|
+
}
|
105
|
+
|
106
|
+
static VALUE Xorshift64Star_eq(VALUE self, VALUE v) {
|
107
|
+
return ( ( rb_obj_classname( self ) == rb_obj_classname( v ) ) && ( rb_iv_get( self, "@old_seed" ) == rb_funcall( v, rb_intern( "seed" ), 0 ) ) ) ? Qtrue : Qfalse ;
|
108
|
+
}
|
109
|
+
|
110
|
+
void Init_ext() {
|
111
|
+
CryptModule = rb_define_module( "Crypt" );
|
112
|
+
Xorshift64StarClass = rb_define_class_under( CryptModule, "Xorshift64Star", rb_cObject );
|
113
|
+
|
114
|
+
rb_define_alloc_func( Xorshift64StarClass, Xorshift64Star_alloc );
|
115
|
+
rb_define_method( Xorshift64StarClass, "initialize", Xorshift64Star_initialize, -2 );
|
116
|
+
rb_define_method( Xorshift64StarClass, "srand", Xorshift64Star_srand, -2 );
|
117
|
+
rb_define_method( Xorshift64StarClass, "rand", Xorshift64Star_rand, -2 );
|
118
|
+
rb_define_method( Xorshift64StarClass, "new_seed", Xorshift64Star_new_seed, 0 );
|
119
|
+
rb_define_method( Xorshift64StarClass, "seed", Xorshift64Star_seed, 0 );
|
120
|
+
rb_define_method( Xorshift64StarClass, "==", Xorshift64Star_eq, 1 );
|
121
|
+
}
|
data/lib/crypt/isaac.rb
CHANGED
@@ -1,213 +1,16 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# independent streams of quality random numbers.
|
7
|
-
|
8
|
-
class ISAAC
|
9
|
-
|
10
|
-
attr_accessor :randrsl, :randcnt
|
11
|
-
attr_accessor :mm, :aa, :bb, :cc
|
12
|
-
|
13
|
-
# When a Crypt::ISAAC object is created, it needs to be seeded for
|
14
|
-
# random number generation. If the system has a /dev/urandom file,
|
15
|
-
# that will be used to do the seeding by default. If false is explictly
|
16
|
-
# passed when creating the object, it will instead use /dev/random to
|
17
|
-
# generate its seeds. Be warned that this may make for SLOW
|
18
|
-
# initialization.
|
19
|
-
# If the requested source (/dev/urandom or /dev/random) do not exist,
|
20
|
-
# the system will fall back to a simplistic initialization mechanism
|
21
|
-
# using the builtin Mersenne Twister PRNG.
|
22
|
-
|
23
|
-
def initialize(seed = true)
|
24
|
-
@mm = []
|
25
|
-
|
26
|
-
if Integer === seed || Random === seed
|
27
|
-
self.srand(seed)
|
28
|
-
else
|
29
|
-
@seed = seed
|
30
|
-
rnd_source = ( ( seed == true ) || ( seed == false ) ) ?
|
31
|
-
( seed ? '/dev/urandom' : '/dev/random' ) :
|
32
|
-
seed
|
33
|
-
if (FileTest.exist? rnd_source)
|
34
|
-
@randrsl = []
|
35
|
-
File.open(rnd_source,'r') do |r|
|
36
|
-
256.times do |t|
|
37
|
-
z = r.read(4)
|
38
|
-
x = z.unpack('V')[0]
|
39
|
-
@randrsl[t] = x
|
40
|
-
end
|
41
|
-
end
|
42
|
-
randinit(true)
|
43
|
-
else
|
44
|
-
raise "Entropy source (#{rnd_source}) doesn't exist. The ISAAC algorithm can not be seeded."
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
# If seeded with an integer, use that to seed a standard Ruby Mersenne Twister
|
50
|
-
# PRNG, and then use that to generate seed value for ISAAC. This is mostly useful
|
51
|
-
# for producing repeated, deterministic results, which may be needed for testing.
|
52
|
-
def srand(seed)
|
53
|
-
@seed = seed
|
54
|
-
@randrsl = []
|
55
|
-
seed_prng = ( Random === seed ) ? seed : Random.new(seed)
|
56
|
-
256.times do |t|
|
57
|
-
@randrsl[t] = seed_prng.rand(4294967295)
|
58
|
-
end
|
59
|
-
randinit(true)
|
60
|
-
end
|
61
|
-
|
62
|
-
# Works just like the standard rand() function. If called with an
|
63
|
-
# integer argument, rand() will return positive random number in
|
64
|
-
# the range of 0 to (argument - 1). If called without an integer
|
65
|
-
# argument, rand() returns a positive floating point number less than 1.
|
66
|
-
# If called with a Range, returns a number that is in the range.
|
67
|
-
|
68
|
-
def rand(arg = nil)
|
69
|
-
if (@randcnt == 1)
|
70
|
-
isaac
|
71
|
-
@randcnt = 256
|
72
|
-
end
|
73
|
-
@randcnt -= 1
|
74
|
-
if arg.nil?
|
75
|
-
( @randrsl[@randcnt] / 536870912.0 ) % 1
|
76
|
-
elsif Integer === arg || Float === arg
|
77
|
-
@randrsl[@randcnt] % arg
|
78
|
-
elsif Range === arg
|
79
|
-
arg.min + @randrsl[@randcnt] % (arg.max - arg.min)
|
80
|
-
else
|
81
|
-
@randrsl[@randcnt] % Integer(arg)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def seed
|
86
|
-
Random === @seed ? @seed.seed : @seed
|
87
|
-
end
|
88
|
-
|
89
|
-
def state
|
90
|
-
@randrsl + [@randcnt]
|
91
|
-
end
|
92
|
-
|
93
|
-
def ==(gen)
|
94
|
-
self.state == gen.state
|
95
|
-
end
|
96
|
-
|
97
|
-
def bytes(size)
|
98
|
-
buffer = ""
|
99
|
-
( size / 4 ).times { buffer << [rand(4294967295)].pack("L").unpack("aaaa").join }
|
100
|
-
|
101
|
-
if size % 4 != 0
|
102
|
-
buffer << [rand(4294967295)].pack("L").unpack("aaaa")[0..(size % 4 - 1)].join
|
103
|
-
end
|
104
|
-
|
105
|
-
buffer
|
106
|
-
end
|
107
|
-
|
108
|
-
def isaac
|
109
|
-
i = 0
|
110
|
-
x = 0
|
111
|
-
y = 0
|
112
|
-
|
113
|
-
@cc += 1
|
114
|
-
@bb += @cc
|
115
|
-
@bb & 0xffffffff
|
116
|
-
|
117
|
-
while (i < 256) do
|
118
|
-
x = @mm[i]
|
119
|
-
@aa = (@mm[(i + 128) & 255] + (@aa^(@aa << 13)) ) & 0xffffffff
|
120
|
-
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
|
121
|
-
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
|
122
|
-
i += 1
|
123
|
-
|
124
|
-
x = @mm[i]
|
125
|
-
@aa = (@mm[(i+128)&255] + (@aa^(0x03ffffff & (@aa >> 6))) ) & 0xffffffff
|
126
|
-
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
|
127
|
-
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
|
128
|
-
i += 1
|
129
|
-
|
130
|
-
x = @mm[i]
|
131
|
-
@aa = (@mm[(i + 128)&255] + (@aa^(@aa << 2)) ) & 0xffffffff
|
132
|
-
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
|
133
|
-
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
|
134
|
-
i += 1
|
135
|
-
|
136
|
-
x = @mm[i]
|
137
|
-
@aa = (@mm[(i+128)&255] + (@aa^(0x0000ffff & (@aa >> 16))) ) & 0xffffffff
|
138
|
-
@mm[i] = y = (@mm[(x>>2)&255] + @aa + @bb ) & 0xffffffff
|
139
|
-
@randrsl[i] = @bb = (@mm[(y>>10)&255] + x ) & 0xffffffff
|
140
|
-
i += 1
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
def randinit(flag)
|
145
|
-
i = 0
|
146
|
-
a = 0
|
147
|
-
b = 0
|
148
|
-
c = 0
|
149
|
-
d = 0
|
150
|
-
e = 0
|
151
|
-
f = 0
|
152
|
-
g = 0
|
153
|
-
@aa = @bb = @cc = 0
|
154
|
-
a = b = c = d = e = f = g = h = 0x9e3779b9
|
155
|
-
|
156
|
-
while (i < 4) do
|
157
|
-
a ^= b<<1; d += a; b += c
|
158
|
-
b ^= 0x3fffffff & (c>>2); e += b; c += d
|
159
|
-
c ^= d << 8; f += c; d += e
|
160
|
-
d ^= 0x0000ffff & (e >> 16); g += d; e += f
|
161
|
-
e ^= f << 10; h += e; f += g
|
162
|
-
f ^= 0x0fffffff & (g >> 4); a += f; g += h
|
163
|
-
g ^= h << 8; b += g; h += a
|
164
|
-
h ^= 0x007fffff & (a >> 9); c += h; a += b
|
165
|
-
i += 1
|
166
|
-
end
|
167
|
-
|
168
|
-
i = 0
|
169
|
-
while (i < 256) do
|
170
|
-
if (flag)
|
171
|
-
a+=@randrsl[i ].to_i; b+=@randrsl[i+1].to_i;
|
172
|
-
c+=@randrsl[i+2]; d+=@randrsl[i+3];
|
173
|
-
e+=@randrsl[i+4]; f+=@randrsl[i+5];
|
174
|
-
g+=@randrsl[i+6]; h+=@randrsl[i+7];
|
175
|
-
end
|
176
|
-
|
177
|
-
a^=b<<11; d+=a; b+=c;
|
178
|
-
b^=0x3fffffff & (c>>2); e+=b; c+=d;
|
179
|
-
c^=d<<8; f+=c; d+=e;
|
180
|
-
d^=0x0000ffff & (e>>16); g+=d; e+=f;
|
181
|
-
e^=f<<10; h+=e; f+=g;
|
182
|
-
f^=0x0fffffff & (g>>4); a+=f; g+=h;
|
183
|
-
g^=h<<8; b+=g; h+=a;
|
184
|
-
h^=0x007fffff & (a>>9); c+=h; a+=b;
|
185
|
-
@mm[i]=a;@mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
|
186
|
-
@mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
|
187
|
-
i += 8
|
188
|
-
end
|
189
|
-
|
190
|
-
if flag
|
191
|
-
i = 0
|
192
|
-
while (i < 256)
|
193
|
-
a+=@mm[i ]; b+=@mm[i+1]; c+=@mm[i+2]; d+=@mm[i+3];
|
194
|
-
e+=@mm[i+4]; f+=@mm[i+5]; g+=@mm[i+6]; h+=@mm[i+7];
|
195
|
-
a^=b<<11; d+=a; b+=c;
|
196
|
-
b^=0x3fffffff & (c>>2); e+=b; c+=d;
|
197
|
-
c^=d<<8; f+=c; d+=e;
|
198
|
-
d^=0x0000ffff & (e>>16); g+=d; e+=f;
|
199
|
-
e^=f<<10; h+=e; f+=g;
|
200
|
-
f^=0x0fffffff & (g>>4); a+=f; g+=h;
|
201
|
-
g^=h<<8; b+=g; h+=a;
|
202
|
-
h^=0x007fffff & (a>>9); c+=h; a+=b;
|
203
|
-
@mm[i ]=a; @mm[i+1]=b; @mm[i+2]=c; @mm[i+3]=d;
|
204
|
-
@mm[i+4]=e; @mm[i+5]=f; @mm[i+6]=g; @mm[i+7]=h;
|
205
|
-
i += 8
|
206
|
-
end
|
207
|
-
end
|
1
|
+
begin
|
2
|
+
require 'crypt/isaac/ext'
|
3
|
+
rescue LoadError
|
4
|
+
require 'crypt/isaac/pure'
|
5
|
+
end
|
208
6
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
7
|
+
begin
|
8
|
+
# Use a non-cryptographic alternative to the Mersenne Twister for an internal
|
9
|
+
# pseudo-random source of numbers if the library is required to seed itself.
|
10
|
+
# https://en.wikipedia.org/wiki/Xorshift
|
11
|
+
require 'crypt-xorshift'
|
12
|
+
rescue LoadError
|
13
|
+
# Fallback on an internal micro-implementation.
|
14
|
+
require 'crypt/isaac/xorshift'
|
213
15
|
end
|
16
|
+
|