crypt-isaac 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|