prng-isaac 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/COPYING +3 -0
- data/README.md +9 -0
- data/RELEASE-NOTES +29 -0
- data/bench/bench.rb +30 -0
- data/ext/isaac/Makefile +236 -0
- data/ext/isaac/extconf.rb +2 -0
- data/ext/isaac/isaac.c +246 -0
- data/ext/isaac/rand.c +139 -0
- data/ext/isaac/rand.h +60 -0
- data/ext/isaac/rand4.c +131 -0
- data/ext/isaac/rand4.h +49 -0
- data/test/test_isaac.rb +63 -0
- metadata +68 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fd8d645800d3a280bb5a18a530c4f16ffb90d916
|
4
|
+
data.tar.gz: f5b5184556e7a028239a1f7510cde907d2dae435
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 16898f276eb280b6d476252acf75ccf84dc21f257734e7d0facf13a63cd86bd4ea912930927ddacd4b4953aa0b6e09f5cb31935d11f7be06d8f1c247500cd404
|
7
|
+
data.tar.gz: 717f2707e46c45b6192e4dfa7244d07c2a23a80c93ec9dabd1cf5ada547b0f5e806f769c0dacccf218fc584bcdaf625b73ca869d35c8dced004a668ef5dd6d37
|
data/COPYING
ADDED
data/README.md
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# ISAAC #
|
2
|
+
|
3
|
+
A pseudorandom number generator based on http://burtleburtle.net/bob/rand/isaac.html.
|
4
|
+
|
5
|
+
Sometimes useful for simulation in place of MT19937 (which ruby's #rand is based on), even though ISAAC's number distribution quality is not as good, because it is faster and the state is lighter, so you can have many of them.
|
6
|
+
|
7
|
+
This is useful when you need multiple pseudo-random sequences that are _independent_ and _recreatable_.
|
8
|
+
|
9
|
+
If you care about small state and not cryptographic security, use ISAAC4: the state is about 48 bytes rather then 2K.
|
data/RELEASE-NOTES
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
isaac 0.0.5
|
2
|
+
|
3
|
+
* Classes are in PRNG module.
|
4
|
+
|
5
|
+
* Added ISAAC4 for simulation (not crypo).
|
6
|
+
|
7
|
+
* Add unit tests.
|
8
|
+
|
9
|
+
isaac 0.0.4
|
10
|
+
|
11
|
+
* Update for ruby 1.9 and 2.0.
|
12
|
+
|
13
|
+
isaac 0.0.3
|
14
|
+
|
15
|
+
* Based on Bob Jenkins' comments on ruby-talk, use 256-entry state vectors, rather than 16-entry. Also, some benchmarking (bench/bench.rb) verifies that,
|
16
|
+
for long sequences, 256-entry state vectors are slightly faster, so even for simulation there is not much reason to use 16-entry vectors, unless you have a large number of sequences.
|
17
|
+
|
18
|
+
* Fixed #srand so that it clears the entire state before setting the seed, so
|
19
|
+
that an instance can be reset to produce the same sequence. However, #srand no
|
20
|
+
longer returns the current state values, since they may differ from the original seed values.
|
21
|
+
|
22
|
+
isaac 0.0.2
|
23
|
+
|
24
|
+
* First public release
|
25
|
+
|
26
|
+
isaac 0.0.1
|
27
|
+
|
28
|
+
* Working wrapper around Bob Jenkins' ISAAC code.
|
29
|
+
|
data/bench/bench.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
require 'isaac'
|
3
|
+
|
4
|
+
include PRNG
|
5
|
+
|
6
|
+
srand(1) # use ruby's prng to seed isaac
|
7
|
+
ary = (0..255).map {rand(2**32-1)}
|
8
|
+
r = ISAAC.new
|
9
|
+
r.srand(ary)
|
10
|
+
|
11
|
+
times = Benchmark.measure do
|
12
|
+
1_000_000.times do
|
13
|
+
r.rand32
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
puts times
|
18
|
+
|
19
|
+
__END__
|
20
|
+
|
21
|
+
Times to generate 1_000_000 numbers:
|
22
|
+
|
23
|
+
With 256 entry state vectors (crypto):
|
24
|
+
1.860000 0.200000 2.060000 ( 2.185345) # 2005 ThinkPad
|
25
|
+
0.780000 0.000000 0.780000 ( 0.782771) # 2008 Eee901
|
26
|
+
|
27
|
+
With 16 entry state vectors (ok for simulation):
|
28
|
+
1.900000 0.200000 2.100000 ( 2.224832) # 2005 ThinkPad
|
29
|
+
0.940000 0.000000 0.940000 ( 0.947986) # 2008 Eee901
|
30
|
+
|
data/ext/isaac/Makefile
ADDED
@@ -0,0 +1,236 @@
|
|
1
|
+
|
2
|
+
SHELL = /bin/sh
|
3
|
+
|
4
|
+
# V=0 quiet, V=1 verbose. other values don't work.
|
5
|
+
V = 0
|
6
|
+
Q1 = $(V:1=)
|
7
|
+
Q = $(Q1:0=@)
|
8
|
+
ECHO1 = $(V:1=@:)
|
9
|
+
ECHO = $(ECHO1:0=@echo)
|
10
|
+
|
11
|
+
#### Start of system configuration section. ####
|
12
|
+
|
13
|
+
srcdir = .
|
14
|
+
topdir = $(includedir)/$(RUBY_VERSION_NAME)
|
15
|
+
hdrdir = $(includedir)/$(RUBY_VERSION_NAME)
|
16
|
+
arch_hdrdir = $(rubyhdrdir)/$(arch)
|
17
|
+
PATH_SEPARATOR = :
|
18
|
+
VPATH = $(srcdir):$(arch_hdrdir)/ruby:$(hdrdir)/ruby
|
19
|
+
prefix = $(DESTDIR)/usr/local
|
20
|
+
rubysitearchprefix = $(rubylibprefix)/$(sitearch)
|
21
|
+
rubyarchprefix = $(rubylibprefix)/$(arch)
|
22
|
+
rubylibprefix = $(libdir)/$(RUBY_BASE_NAME)
|
23
|
+
exec_prefix = $(prefix)
|
24
|
+
vendorarchhdrdir = $(vendorhdrdir)/$(sitearch)
|
25
|
+
sitearchhdrdir = $(sitehdrdir)/$(sitearch)
|
26
|
+
rubyarchhdrdir = $(rubyhdrdir)/$(arch)
|
27
|
+
vendorhdrdir = $(rubyhdrdir)/vendor_ruby
|
28
|
+
sitehdrdir = $(rubyhdrdir)/site_ruby
|
29
|
+
rubyhdrdir = $(includedir)/$(RUBY_VERSION_NAME)
|
30
|
+
vendorarchdir = $(vendorlibdir)/$(sitearch)
|
31
|
+
vendorlibdir = $(vendordir)/$(ruby_version)
|
32
|
+
vendordir = $(rubylibprefix)/vendor_ruby
|
33
|
+
sitearchdir = $(sitelibdir)/$(sitearch)
|
34
|
+
sitelibdir = $(sitedir)/$(ruby_version)
|
35
|
+
sitedir = $(rubylibprefix)/site_ruby
|
36
|
+
rubyarchdir = $(rubylibdir)/$(arch)
|
37
|
+
rubylibdir = $(rubylibprefix)/$(ruby_version)
|
38
|
+
sitearchincludedir = $(includedir)/$(sitearch)
|
39
|
+
archincludedir = $(includedir)/$(arch)
|
40
|
+
sitearchlibdir = $(libdir)/$(sitearch)
|
41
|
+
archlibdir = $(libdir)/$(arch)
|
42
|
+
ridir = $(datarootdir)/$(RI_BASE_NAME)
|
43
|
+
mandir = $(datarootdir)/man
|
44
|
+
localedir = $(datarootdir)/locale
|
45
|
+
libdir = $(exec_prefix)/lib
|
46
|
+
psdir = $(docdir)
|
47
|
+
pdfdir = $(docdir)
|
48
|
+
dvidir = $(docdir)
|
49
|
+
htmldir = $(docdir)
|
50
|
+
infodir = $(datarootdir)/info
|
51
|
+
docdir = $(datarootdir)/doc/$(PACKAGE)
|
52
|
+
oldincludedir = $(DESTDIR)/usr/include
|
53
|
+
includedir = $(prefix)/include
|
54
|
+
localstatedir = $(prefix)/var
|
55
|
+
sharedstatedir = $(prefix)/com
|
56
|
+
sysconfdir = $(prefix)/etc
|
57
|
+
datadir = $(datarootdir)
|
58
|
+
datarootdir = $(prefix)/share
|
59
|
+
libexecdir = $(exec_prefix)/libexec
|
60
|
+
sbindir = $(exec_prefix)/sbin
|
61
|
+
bindir = $(exec_prefix)/bin
|
62
|
+
archdir = $(rubyarchdir)
|
63
|
+
|
64
|
+
|
65
|
+
CC = gcc
|
66
|
+
CXX = g++
|
67
|
+
LIBRUBY = $(LIBRUBY_A)
|
68
|
+
LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a
|
69
|
+
LIBRUBYARG_SHARED = -Wl,-R -Wl,$(libdir) -L$(libdir)
|
70
|
+
LIBRUBYARG_STATIC = -Wl,-R -Wl,$(libdir) -L$(libdir) -l$(RUBY_SO_NAME)-static
|
71
|
+
empty =
|
72
|
+
OUTFLAG = -o $(empty)
|
73
|
+
COUTFLAG = -o $(empty)
|
74
|
+
|
75
|
+
RUBY_EXTCONF_H =
|
76
|
+
cflags = $(optflags) $(debugflags) $(warnflags)
|
77
|
+
optflags = -O3 -fno-fast-math
|
78
|
+
debugflags = -ggdb3
|
79
|
+
warnflags = -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration
|
80
|
+
CFLAGS = -fPIC $(cflags) $(ARCH_FLAG)
|
81
|
+
INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir)
|
82
|
+
DEFS =
|
83
|
+
CPPFLAGS = $(DEFS) $(cppflags)
|
84
|
+
CXXFLAGS = $(CFLAGS) $(cxxflags)
|
85
|
+
ldflags = -L. -fstack-protector -rdynamic -Wl,-export-dynamic
|
86
|
+
dldflags =
|
87
|
+
ARCH_FLAG =
|
88
|
+
DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
|
89
|
+
LDSHARED = $(CC) -shared
|
90
|
+
LDSHAREDXX = $(CXX) -shared
|
91
|
+
AR = ar
|
92
|
+
EXEEXT =
|
93
|
+
|
94
|
+
RUBY_INSTALL_NAME = ruby
|
95
|
+
RUBY_SO_NAME = ruby
|
96
|
+
RUBYW_INSTALL_NAME =
|
97
|
+
RUBY_VERSION_NAME = $(RUBY_BASE_NAME)-$(ruby_version)
|
98
|
+
RUBYW_BASE_NAME = rubyw
|
99
|
+
RUBY_BASE_NAME = ruby
|
100
|
+
|
101
|
+
arch = x86_64-linux
|
102
|
+
sitearch = $(arch)
|
103
|
+
ruby_version = 2.0.0
|
104
|
+
ruby = $(bindir)/ruby
|
105
|
+
RUBY = $(ruby)
|
106
|
+
ruby_headers = $(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h $(arch_hdrdir)/ruby/config.h
|
107
|
+
|
108
|
+
RM = rm -f
|
109
|
+
RM_RF = $(RUBY) -run -e rm -- -rf
|
110
|
+
RMDIRS = rmdir --ignore-fail-on-non-empty -p
|
111
|
+
MAKEDIRS = /bin/mkdir -p
|
112
|
+
INSTALL = /usr/bin/install -c
|
113
|
+
INSTALL_PROG = $(INSTALL) -m 0755
|
114
|
+
INSTALL_DATA = $(INSTALL) -m 644
|
115
|
+
COPY = cp
|
116
|
+
TOUCH = exit >
|
117
|
+
|
118
|
+
#### End of system configuration section. ####
|
119
|
+
|
120
|
+
preload =
|
121
|
+
|
122
|
+
libpath = . $(libdir)
|
123
|
+
LIBPATH = -L. -L$(libdir) -Wl,-R$(libdir)
|
124
|
+
DEFFILE =
|
125
|
+
|
126
|
+
CLEANFILES = mkmf.log
|
127
|
+
DISTCLEANFILES =
|
128
|
+
DISTCLEANDIRS =
|
129
|
+
|
130
|
+
extout =
|
131
|
+
extout_prefix =
|
132
|
+
target_prefix =
|
133
|
+
LOCAL_LIBS =
|
134
|
+
LIBS = -lpthread -lrt -ldl -lcrypt -lm -lc
|
135
|
+
ORIG_SRCS = isaac.c rand4.c rand.c
|
136
|
+
SRCS = $(ORIG_SRCS)
|
137
|
+
OBJS = isaac.o rand4.o rand.o
|
138
|
+
HDRS = $(srcdir)/rand4.h $(srcdir)/rand.h
|
139
|
+
TARGET = isaac
|
140
|
+
TARGET_NAME = isaac
|
141
|
+
TARGET_ENTRY = Init_$(TARGET_NAME)
|
142
|
+
DLLIB = $(TARGET).so
|
143
|
+
EXTSTATIC =
|
144
|
+
STATIC_LIB =
|
145
|
+
|
146
|
+
BINDIR = $(bindir)
|
147
|
+
RUBYCOMMONDIR = $(sitedir)$(target_prefix)
|
148
|
+
RUBYLIBDIR = $(sitelibdir)$(target_prefix)
|
149
|
+
RUBYARCHDIR = $(sitearchdir)$(target_prefix)
|
150
|
+
HDRDIR = $(rubyhdrdir)/ruby$(target_prefix)
|
151
|
+
ARCHHDRDIR = $(rubyhdrdir)/$(arch)/ruby$(target_prefix)
|
152
|
+
|
153
|
+
TARGET_SO = $(DLLIB)
|
154
|
+
CLEANLIBS = $(TARGET).so
|
155
|
+
CLEANOBJS = *.o *.bak
|
156
|
+
|
157
|
+
all: $(DLLIB)
|
158
|
+
static: $(STATIC_LIB)
|
159
|
+
.PHONY: all install static install-so install-rb
|
160
|
+
.PHONY: clean clean-so clean-static clean-rb
|
161
|
+
|
162
|
+
clean-static::
|
163
|
+
clean-rb-default::
|
164
|
+
clean-rb::
|
165
|
+
clean-so::
|
166
|
+
clean: clean-so clean-static clean-rb-default clean-rb
|
167
|
+
-$(Q)$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) .*.time
|
168
|
+
|
169
|
+
distclean-rb-default::
|
170
|
+
distclean-rb::
|
171
|
+
distclean-so::
|
172
|
+
distclean-static::
|
173
|
+
distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
|
174
|
+
-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
|
175
|
+
-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
|
176
|
+
-$(Q)$(RMDIRS) $(DISTCLEANDIRS) 2> /dev/null || true
|
177
|
+
|
178
|
+
realclean: distclean
|
179
|
+
install: install-so install-rb
|
180
|
+
|
181
|
+
install-so: $(DLLIB) ./.RUBYARCHDIR.time
|
182
|
+
$(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR)
|
183
|
+
clean-static::
|
184
|
+
-$(Q)$(RM) $(STATIC_LIB)
|
185
|
+
install-rb: pre-install-rb install-rb-default
|
186
|
+
install-rb-default: pre-install-rb-default
|
187
|
+
pre-install-rb: Makefile
|
188
|
+
pre-install-rb-default: Makefile
|
189
|
+
pre-install-rb-default:
|
190
|
+
$(ECHO) installing default isaac libraries
|
191
|
+
./.RUBYARCHDIR.time:
|
192
|
+
$(Q) $(MAKEDIRS) $(RUBYARCHDIR)
|
193
|
+
$(Q) $(TOUCH) $@
|
194
|
+
|
195
|
+
site-install: site-install-so site-install-rb
|
196
|
+
site-install-so: install-so
|
197
|
+
site-install-rb: install-rb
|
198
|
+
|
199
|
+
.SUFFIXES: .c .m .cc .mm .cxx .cpp .C .o
|
200
|
+
|
201
|
+
.cc.o:
|
202
|
+
$(ECHO) compiling $(<)
|
203
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
204
|
+
|
205
|
+
.mm.o:
|
206
|
+
$(ECHO) compiling $(<)
|
207
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
208
|
+
|
209
|
+
.cxx.o:
|
210
|
+
$(ECHO) compiling $(<)
|
211
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
212
|
+
|
213
|
+
.cpp.o:
|
214
|
+
$(ECHO) compiling $(<)
|
215
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
216
|
+
|
217
|
+
.C.o:
|
218
|
+
$(ECHO) compiling $(<)
|
219
|
+
$(Q) $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<
|
220
|
+
|
221
|
+
.c.o:
|
222
|
+
$(ECHO) compiling $(<)
|
223
|
+
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
|
224
|
+
|
225
|
+
.m.o:
|
226
|
+
$(ECHO) compiling $(<)
|
227
|
+
$(Q) $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<
|
228
|
+
|
229
|
+
$(DLLIB): $(OBJS) Makefile
|
230
|
+
$(ECHO) linking shared-object $(DLLIB)
|
231
|
+
-$(Q)$(RM) $(@)
|
232
|
+
$(Q) $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)
|
233
|
+
|
234
|
+
|
235
|
+
|
236
|
+
$(OBJS): $(HDRS) $(ruby_headers)
|
data/ext/isaac/isaac.c
ADDED
@@ -0,0 +1,246 @@
|
|
1
|
+
#include "ruby.h"
|
2
|
+
#include "rand.h"
|
3
|
+
#include "rand4.h"
|
4
|
+
|
5
|
+
#ifndef min
|
6
|
+
# define min(a,b) (((a)<(b)) ? (a) : (b))
|
7
|
+
#endif /* min */
|
8
|
+
|
9
|
+
static VALUE
|
10
|
+
ISAAC_s_allocate(VALUE klass)
|
11
|
+
{
|
12
|
+
randctx *ctx;
|
13
|
+
|
14
|
+
return Data_Make_Struct(klass, randctx, NULL, NULL, ctx);
|
15
|
+
}
|
16
|
+
|
17
|
+
static VALUE
|
18
|
+
ISAAC4_s_allocate(VALUE klass)
|
19
|
+
{
|
20
|
+
randctx4 *ctx;
|
21
|
+
|
22
|
+
return Data_Make_Struct(klass, randctx4, NULL, NULL, ctx);
|
23
|
+
}
|
24
|
+
|
25
|
+
/*
|
26
|
+
* Seed the generator with an array of up to ISAAC::RANDSIZ integers in the
|
27
|
+
* range 0..2**32-1. More entries are ignored. Missing entries are treated
|
28
|
+
* as 0. Returns +nil+.
|
29
|
+
*/
|
30
|
+
static VALUE
|
31
|
+
ISAAC_srand(VALUE self, VALUE ary)
|
32
|
+
{
|
33
|
+
int i;
|
34
|
+
randctx *ctx;
|
35
|
+
|
36
|
+
Check_Type(ary, T_ARRAY);
|
37
|
+
|
38
|
+
Data_Get_Struct(self, randctx, ctx);
|
39
|
+
|
40
|
+
MEMZERO(ctx, randctx, 1);
|
41
|
+
for (i=min(RANDSIZ, RARRAY_LEN(ary))-1; i>=0; i--) {
|
42
|
+
ctx->randrsl[i] = NUM2UINT(RARRAY_PTR(ary)[i]);
|
43
|
+
}
|
44
|
+
isaac_init(ctx, 1);
|
45
|
+
|
46
|
+
return Qnil;
|
47
|
+
}
|
48
|
+
|
49
|
+
/*
|
50
|
+
* Seed the generator with an array of up to ISAAC::RANDSIZ integers in the
|
51
|
+
* range 0..2**32-1. More entries are ignored. Missing entries are treated
|
52
|
+
* as 0. Returns +nil+.
|
53
|
+
*/
|
54
|
+
static VALUE
|
55
|
+
ISAAC4_srand(VALUE self, VALUE ary)
|
56
|
+
{
|
57
|
+
int i;
|
58
|
+
randctx4 *ctx;
|
59
|
+
|
60
|
+
Check_Type(ary, T_ARRAY);
|
61
|
+
|
62
|
+
Data_Get_Struct(self, randctx4, ctx);
|
63
|
+
|
64
|
+
MEMZERO(ctx, randctx4, 1);
|
65
|
+
for (i=min(RANDSIZ4, RARRAY_LEN(ary))-1; i>=0; i--) {
|
66
|
+
ctx->randrsl[i] = NUM2UINT(RARRAY_PTR(ary)[i]);
|
67
|
+
}
|
68
|
+
isaac_init4(ctx, 1);
|
69
|
+
|
70
|
+
return Qnil;
|
71
|
+
}
|
72
|
+
|
73
|
+
/*
|
74
|
+
* Return a random integer in the range 0..2**32-1.
|
75
|
+
*/
|
76
|
+
static VALUE
|
77
|
+
ISAAC_rand32(VALUE self)
|
78
|
+
{
|
79
|
+
randctx *ctx;
|
80
|
+
|
81
|
+
Data_Get_Struct(self, randctx, ctx);
|
82
|
+
|
83
|
+
if (!ctx->randcnt--) {
|
84
|
+
isaac_rand(ctx);
|
85
|
+
ctx->randcnt=RANDSIZ-1;
|
86
|
+
}
|
87
|
+
|
88
|
+
return UINT2NUM(ctx->randrsl[ctx->randcnt]);
|
89
|
+
}
|
90
|
+
|
91
|
+
/*
|
92
|
+
* Return a random integer in the range 0..2**32-1.
|
93
|
+
*/
|
94
|
+
static VALUE
|
95
|
+
ISAAC4_rand32(VALUE self)
|
96
|
+
{
|
97
|
+
randctx4 *ctx;
|
98
|
+
|
99
|
+
Data_Get_Struct(self, randctx4, ctx);
|
100
|
+
|
101
|
+
if (!ctx->randcnt--) {
|
102
|
+
isaac_rand4(ctx);
|
103
|
+
ctx->randcnt=RANDSIZ4-1;
|
104
|
+
}
|
105
|
+
|
106
|
+
return UINT2NUM(ctx->randrsl[ctx->randcnt]);
|
107
|
+
}
|
108
|
+
|
109
|
+
/*
|
110
|
+
* Return a random float in the range 0..1.
|
111
|
+
*/
|
112
|
+
static VALUE
|
113
|
+
ISAAC_rand(VALUE self)
|
114
|
+
{
|
115
|
+
randctx *ctx;
|
116
|
+
|
117
|
+
Data_Get_Struct(self, randctx, ctx);
|
118
|
+
|
119
|
+
if (!ctx->randcnt--) {
|
120
|
+
isaac_rand(ctx);
|
121
|
+
ctx->randcnt=RANDSIZ-1;
|
122
|
+
}
|
123
|
+
|
124
|
+
return rb_float_new(ctx->randrsl[ctx->randcnt] / 4294967295.0);
|
125
|
+
}
|
126
|
+
|
127
|
+
/*
|
128
|
+
* Return a random float in the range 0..1.
|
129
|
+
*/
|
130
|
+
static VALUE
|
131
|
+
ISAAC4_rand(VALUE self)
|
132
|
+
{
|
133
|
+
randctx4 *ctx;
|
134
|
+
|
135
|
+
Data_Get_Struct(self, randctx4, ctx);
|
136
|
+
|
137
|
+
if (!ctx->randcnt--) {
|
138
|
+
isaac_rand4(ctx);
|
139
|
+
ctx->randcnt=RANDSIZ4-1;
|
140
|
+
}
|
141
|
+
|
142
|
+
return rb_float_new(ctx->randrsl[ctx->randcnt] / 4294967295.0);
|
143
|
+
}
|
144
|
+
|
145
|
+
static VALUE
|
146
|
+
ISAAC_marshal_dump(VALUE self)
|
147
|
+
{
|
148
|
+
randctx *ctx;
|
149
|
+
int i;
|
150
|
+
int ary_size = sizeof(randctx)/sizeof(ub4);
|
151
|
+
VALUE ary;
|
152
|
+
|
153
|
+
Data_Get_Struct(self, randctx, ctx);
|
154
|
+
|
155
|
+
ary = rb_ary_new2(ary_size);
|
156
|
+
for (i = 0; i < ary_size; i++) {
|
157
|
+
rb_ary_push(ary, UINT2NUM(((ub4 *)ctx)[i]));
|
158
|
+
}
|
159
|
+
|
160
|
+
return ary;
|
161
|
+
}
|
162
|
+
|
163
|
+
static VALUE
|
164
|
+
ISAAC4_marshal_dump(VALUE self)
|
165
|
+
{
|
166
|
+
randctx4 *ctx;
|
167
|
+
int i;
|
168
|
+
int ary_size = sizeof(randctx4)/sizeof(ub4);
|
169
|
+
VALUE ary;
|
170
|
+
|
171
|
+
Data_Get_Struct(self, randctx4, ctx);
|
172
|
+
|
173
|
+
ary = rb_ary_new2(ary_size);
|
174
|
+
for (i = 0; i < ary_size; i++) {
|
175
|
+
rb_ary_push(ary, UINT2NUM(((ub4 *)ctx)[i]));
|
176
|
+
}
|
177
|
+
|
178
|
+
return ary;
|
179
|
+
}
|
180
|
+
|
181
|
+
static VALUE
|
182
|
+
ISAAC_marshal_load(VALUE self, VALUE ary)
|
183
|
+
{
|
184
|
+
randctx *ctx;
|
185
|
+
int i;
|
186
|
+
int ary_size = sizeof(randctx)/sizeof(ub4);
|
187
|
+
|
188
|
+
Data_Get_Struct(self, randctx, ctx);
|
189
|
+
|
190
|
+
if (RARRAY_LEN(ary) != ary_size)
|
191
|
+
rb_raise(rb_eArgError, "bad length in loaded ISAAC data");
|
192
|
+
|
193
|
+
for (i = 0; i < ary_size; i++) {
|
194
|
+
((ub4 *)ctx)[i] = NUM2UINT(RARRAY_PTR(ary)[i]);
|
195
|
+
}
|
196
|
+
|
197
|
+
return self;
|
198
|
+
}
|
199
|
+
|
200
|
+
static VALUE
|
201
|
+
ISAAC4_marshal_load(VALUE self, VALUE ary)
|
202
|
+
{
|
203
|
+
randctx4 *ctx;
|
204
|
+
int i;
|
205
|
+
int ary_size = sizeof(randctx4)/sizeof(ub4);
|
206
|
+
|
207
|
+
Data_Get_Struct(self, randctx4, ctx);
|
208
|
+
|
209
|
+
if (RARRAY_LEN(ary) != ary_size)
|
210
|
+
rb_raise(rb_eArgError, "bad length in loaded ISAAC4 data");
|
211
|
+
|
212
|
+
for (i = 0; i < ary_size; i++) {
|
213
|
+
((ub4 *)ctx)[i] = NUM2UINT(RARRAY_PTR(ary)[i]);
|
214
|
+
}
|
215
|
+
|
216
|
+
return self;
|
217
|
+
}
|
218
|
+
|
219
|
+
void
|
220
|
+
Init_isaac()
|
221
|
+
{
|
222
|
+
VALUE ISAAC;
|
223
|
+
VALUE ISAAC4;
|
224
|
+
VALUE mPRNG;
|
225
|
+
|
226
|
+
mPRNG = rb_define_module("PRNG");
|
227
|
+
ISAAC = rb_define_class_under(mPRNG, "ISAAC", rb_cObject);
|
228
|
+
ISAAC4 = rb_define_class_under(mPRNG, "ISAAC4", rb_cObject);
|
229
|
+
|
230
|
+
rb_define_alloc_func(ISAAC, ISAAC_s_allocate);
|
231
|
+
rb_define_method(ISAAC, "srand", ISAAC_srand, 1);
|
232
|
+
rb_define_method(ISAAC, "rand32", ISAAC_rand32, 0);
|
233
|
+
rb_define_method(ISAAC, "rand", ISAAC_rand, 0);
|
234
|
+
rb_define_method(ISAAC, "marshal_dump", ISAAC_marshal_dump, 0);
|
235
|
+
rb_define_method(ISAAC, "marshal_load", ISAAC_marshal_load, 1);
|
236
|
+
|
237
|
+
rb_define_alloc_func(ISAAC4, ISAAC4_s_allocate);
|
238
|
+
rb_define_method(ISAAC4, "srand", ISAAC4_srand, 1);
|
239
|
+
rb_define_method(ISAAC4, "rand32", ISAAC4_rand32, 0);
|
240
|
+
rb_define_method(ISAAC4, "rand", ISAAC4_rand, 0);
|
241
|
+
rb_define_method(ISAAC4, "marshal_dump", ISAAC4_marshal_dump, 0);
|
242
|
+
rb_define_method(ISAAC4, "marshal_load", ISAAC4_marshal_load, 1);
|
243
|
+
|
244
|
+
rb_const_set(ISAAC, rb_intern("RANDSIZ"), UINT2NUM(RANDSIZ));
|
245
|
+
rb_const_set(ISAAC4, rb_intern("RANDSIZ"), UINT2NUM(RANDSIZ4));
|
246
|
+
}
|
data/ext/isaac/rand.c
ADDED
@@ -0,0 +1,139 @@
|
|
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: added main (ifdef'ed out), also rearranged randinit()
|
8
|
+
010626: Note that this is public domain
|
9
|
+
|
10
|
+
ADAPTED Aug2004 for use in Ruby by Joel VanderWerf
|
11
|
+
ADAPTED Jan2010 for 64 bit systems (same algorithm and results as 32 bit)
|
12
|
+
------------------------------------------------------------------------------
|
13
|
+
*/
|
14
|
+
#ifndef RAND
|
15
|
+
#include "rand.h"
|
16
|
+
#endif
|
17
|
+
|
18
|
+
|
19
|
+
#define ind(mm,x) ((mm)[(x>>2)&(RANDSIZ-1)])
|
20
|
+
#define rngstep(mix,a,b,mm,m,m2,r,x) \
|
21
|
+
{ \
|
22
|
+
x = *m; \
|
23
|
+
a = ((a^(mix)) + *(m2++)); \
|
24
|
+
*(m++) = y = (ind(mm,x) + a + b); \
|
25
|
+
*(r++) = b = (ind(mm,y>>RANDSIZL) + x); \
|
26
|
+
}
|
27
|
+
|
28
|
+
void isaac_rand(ctx)
|
29
|
+
randctx *ctx;
|
30
|
+
{
|
31
|
+
register ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
|
32
|
+
mm=ctx->randmem; r=ctx->randrsl;
|
33
|
+
a = ctx->randa; b = (ctx->randb + (++ctx->randc));
|
34
|
+
for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
|
35
|
+
{
|
36
|
+
rngstep( a<<13, a, b, mm, m, m2, r, x);
|
37
|
+
rngstep( a>>6 , a, b, mm, m, m2, r, x);
|
38
|
+
rngstep( a<<2 , a, b, mm, m, m2, r, x);
|
39
|
+
rngstep( a>>16, a, b, mm, m, m2, r, x);
|
40
|
+
}
|
41
|
+
for (m2 = mm; m2<mend; )
|
42
|
+
{
|
43
|
+
rngstep( a<<13, a, b, mm, m, m2, r, x);
|
44
|
+
rngstep( a>>6 , a, b, mm, m, m2, r, x);
|
45
|
+
rngstep( a<<2 , a, b, mm, m, m2, r, x);
|
46
|
+
rngstep( a>>16, a, b, mm, m, m2, r, x);
|
47
|
+
}
|
48
|
+
ctx->randb = b; ctx->randa = a;
|
49
|
+
}
|
50
|
+
|
51
|
+
|
52
|
+
#define mix(a,b,c,d,e,f,g,h) \
|
53
|
+
{ \
|
54
|
+
a^=b<<11; d+=a; b+=c; \
|
55
|
+
b^=c>>2; e+=b; c+=d; \
|
56
|
+
c^=d<<8; f+=c; d+=e; \
|
57
|
+
d^=e>>16; g+=d; e+=f; \
|
58
|
+
e^=f<<10; h+=e; f+=g; \
|
59
|
+
f^=g>>4; a+=f; g+=h; \
|
60
|
+
g^=h<<8; b+=g; h+=a; \
|
61
|
+
h^=a>>9; c+=h; a+=b; \
|
62
|
+
}
|
63
|
+
|
64
|
+
/* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
|
65
|
+
void isaac_init(ctx, flag)
|
66
|
+
randctx *ctx;
|
67
|
+
int flag;
|
68
|
+
{
|
69
|
+
int i;
|
70
|
+
ub4 a,b,c,d,e,f,g,h;
|
71
|
+
ub4 *m,*r;
|
72
|
+
ctx->randa = ctx->randb = ctx->randc = 0;
|
73
|
+
m=ctx->randmem;
|
74
|
+
r=ctx->randrsl;
|
75
|
+
a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
|
76
|
+
|
77
|
+
for (i=0; i<4; ++i) /* scramble it */
|
78
|
+
{
|
79
|
+
mix(a,b,c,d,e,f,g,h);
|
80
|
+
}
|
81
|
+
|
82
|
+
if (flag)
|
83
|
+
{
|
84
|
+
/* initialize using the contents of r[] as the seed */
|
85
|
+
for (i=0; i<RANDSIZ; i+=8)
|
86
|
+
{
|
87
|
+
a+=r[i ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3];
|
88
|
+
e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7];
|
89
|
+
mix(a,b,c,d,e,f,g,h);
|
90
|
+
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
91
|
+
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
92
|
+
}
|
93
|
+
/* do a second pass to make all of the seed affect all of m */
|
94
|
+
for (i=0; i<RANDSIZ; i+=8)
|
95
|
+
{
|
96
|
+
a+=m[i ]; b+=m[i+1]; c+=m[i+2]; d+=m[i+3];
|
97
|
+
e+=m[i+4]; f+=m[i+5]; g+=m[i+6]; h+=m[i+7];
|
98
|
+
mix(a,b,c,d,e,f,g,h);
|
99
|
+
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
100
|
+
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
101
|
+
}
|
102
|
+
}
|
103
|
+
else
|
104
|
+
{
|
105
|
+
/* fill in mm[] with messy stuff */
|
106
|
+
for (i=0; i<RANDSIZ; i+=8)
|
107
|
+
{
|
108
|
+
mix(a,b,c,d,e,f,g,h);
|
109
|
+
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
110
|
+
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
isaac_rand(ctx); /* fill in the first set of results */
|
115
|
+
ctx->randcnt=RANDSIZ; /* prepare to use the first set of results */
|
116
|
+
}
|
117
|
+
|
118
|
+
|
119
|
+
#ifdef NEVER
|
120
|
+
#include <stdio.h>
|
121
|
+
|
122
|
+
int main()
|
123
|
+
{
|
124
|
+
ub4 i,j;
|
125
|
+
randctx ctx;
|
126
|
+
ctx.randa=ctx.randb=ctx.randc=(ub4)0;
|
127
|
+
for (i=0; i<RANDSIZ; ++i) ctx.randrsl[i]=(ub4)0;
|
128
|
+
isaac_init(&ctx, 1);
|
129
|
+
for (i=0; i<2; ++i)
|
130
|
+
{
|
131
|
+
isaac_rand(&ctx);
|
132
|
+
for (j=0; j<RANDSIZ; ++j)
|
133
|
+
{
|
134
|
+
printf("%.8lx",(long unsigned int)ctx.randrsl[j]);
|
135
|
+
if ((j&7)==7) printf("\n");
|
136
|
+
}
|
137
|
+
}
|
138
|
+
}
|
139
|
+
#endif
|
data/ext/isaac/rand.h
ADDED
@@ -0,0 +1,60 @@
|
|
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
|
+
ADAPTED Aug2004 for use in Ruby by Joel VanderWerf
|
13
|
+
ADAPTED Jan2010 for 64 bit systems (same algorithm and results as 32 bit)
|
14
|
+
------------------------------------------------------------------------------
|
15
|
+
*/
|
16
|
+
|
17
|
+
#include <stdint.h>
|
18
|
+
|
19
|
+
typedef uint32_t ub4;
|
20
|
+
|
21
|
+
#ifndef RAND
|
22
|
+
#define RAND
|
23
|
+
#define RANDSIZL (8) /* I recommend 8 for crypto, 4 for simulations */
|
24
|
+
#define RANDSIZ (1<<RANDSIZL)
|
25
|
+
|
26
|
+
/* context of random number generator */
|
27
|
+
struct randctx
|
28
|
+
{
|
29
|
+
ub4 randcnt;
|
30
|
+
ub4 randrsl[RANDSIZ];
|
31
|
+
ub4 randmem[RANDSIZ];
|
32
|
+
ub4 randa;
|
33
|
+
ub4 randb;
|
34
|
+
ub4 randc;
|
35
|
+
};
|
36
|
+
typedef struct randctx randctx;
|
37
|
+
|
38
|
+
/*
|
39
|
+
------------------------------------------------------------------------------
|
40
|
+
If (flag==TRUE), then use the contents of randrsl[0..RANDSIZ-1] as the seed.
|
41
|
+
------------------------------------------------------------------------------
|
42
|
+
*/
|
43
|
+
void isaac_init(randctx *r, int flag);
|
44
|
+
|
45
|
+
void isaac_rand(randctx *r);
|
46
|
+
|
47
|
+
|
48
|
+
/*
|
49
|
+
------------------------------------------------------------------------------
|
50
|
+
Call rand(/o_ randctx *r _o/) to retrieve a single 32-bit random value
|
51
|
+
------------------------------------------------------------------------------
|
52
|
+
*/
|
53
|
+
#define rand(r) \
|
54
|
+
(!(r)->randcnt-- ? \
|
55
|
+
(isaac_rand(r), (r)->randcnt=RANDSIZ-1, (r)->randrsl[(r)->randcnt]) : \
|
56
|
+
(r)->randrsl[(r)->randcnt])
|
57
|
+
|
58
|
+
#endif /* RAND */
|
59
|
+
|
60
|
+
|
data/ext/isaac/rand4.c
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
/*
|
2
|
+
------------------------------------------------------------------------------
|
3
|
+
rand4.c: rand.c specialized to RANDSIZL=4
|
4
|
+
------------------------------------------------------------------------------
|
5
|
+
*/
|
6
|
+
#ifndef RAND4
|
7
|
+
#include "rand4.h"
|
8
|
+
#endif
|
9
|
+
|
10
|
+
|
11
|
+
#define ind(mm,x) ((mm)[(x>>2)&(RANDSIZ4-1)])
|
12
|
+
#define rngstep(mix,a,b,mm,m,m2,r,x) \
|
13
|
+
{ \
|
14
|
+
x = *m; \
|
15
|
+
a = ((a^(mix)) + *(m2++)); \
|
16
|
+
*(m++) = y = (ind(mm,x) + a + b); \
|
17
|
+
*(r++) = b = (ind(mm,y>>4) + x); \
|
18
|
+
}
|
19
|
+
|
20
|
+
void isaac_rand4(ctx)
|
21
|
+
randctx4 *ctx;
|
22
|
+
{
|
23
|
+
register ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
|
24
|
+
mm=ctx->randmem; r=ctx->randrsl;
|
25
|
+
a = ctx->randa; b = (ctx->randb + (++ctx->randc));
|
26
|
+
for (m = mm, mend = m2 = m+(RANDSIZ4/2); m<mend; )
|
27
|
+
{
|
28
|
+
rngstep( a<<13, a, b, mm, m, m2, r, x);
|
29
|
+
rngstep( a>>6 , a, b, mm, m, m2, r, x);
|
30
|
+
rngstep( a<<2 , a, b, mm, m, m2, r, x);
|
31
|
+
rngstep( a>>16, a, b, mm, m, m2, r, x);
|
32
|
+
}
|
33
|
+
for (m2 = mm; m2<mend; )
|
34
|
+
{
|
35
|
+
rngstep( a<<13, a, b, mm, m, m2, r, x);
|
36
|
+
rngstep( a>>6 , a, b, mm, m, m2, r, x);
|
37
|
+
rngstep( a<<2 , a, b, mm, m, m2, r, x);
|
38
|
+
rngstep( a>>16, a, b, mm, m, m2, r, x);
|
39
|
+
}
|
40
|
+
ctx->randb = b; ctx->randa = a;
|
41
|
+
}
|
42
|
+
|
43
|
+
|
44
|
+
#define mix(a,b,c,d,e,f,g,h) \
|
45
|
+
{ \
|
46
|
+
a^=b<<11; d+=a; b+=c; \
|
47
|
+
b^=c>>2; e+=b; c+=d; \
|
48
|
+
c^=d<<8; f+=c; d+=e; \
|
49
|
+
d^=e>>16; g+=d; e+=f; \
|
50
|
+
e^=f<<10; h+=e; f+=g; \
|
51
|
+
f^=g>>4; a+=f; g+=h; \
|
52
|
+
g^=h<<8; b+=g; h+=a; \
|
53
|
+
h^=a>>9; c+=h; a+=b; \
|
54
|
+
}
|
55
|
+
|
56
|
+
/* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
|
57
|
+
void isaac_init4(ctx, flag)
|
58
|
+
randctx4 *ctx;
|
59
|
+
int flag;
|
60
|
+
{
|
61
|
+
int i;
|
62
|
+
ub4 a,b,c,d,e,f,g,h;
|
63
|
+
ub4 *m,*r;
|
64
|
+
ctx->randa = ctx->randb = ctx->randc = 0;
|
65
|
+
m=ctx->randmem;
|
66
|
+
r=ctx->randrsl;
|
67
|
+
a=b=c=d=e=f=g=h=0x9e3779b9; /* the golden ratio */
|
68
|
+
|
69
|
+
for (i=0; i<4; ++i) /* scramble it */
|
70
|
+
{
|
71
|
+
mix(a,b,c,d,e,f,g,h);
|
72
|
+
}
|
73
|
+
|
74
|
+
if (flag)
|
75
|
+
{
|
76
|
+
/* initialize using the contents of r[] as the seed */
|
77
|
+
for (i=0; i<RANDSIZ4; i+=8)
|
78
|
+
{
|
79
|
+
a+=r[i ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3];
|
80
|
+
e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7];
|
81
|
+
mix(a,b,c,d,e,f,g,h);
|
82
|
+
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
83
|
+
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
84
|
+
}
|
85
|
+
/* do a second pass to make all of the seed affect all of m */
|
86
|
+
for (i=0; i<RANDSIZ4; i+=8)
|
87
|
+
{
|
88
|
+
a+=m[i ]; b+=m[i+1]; c+=m[i+2]; d+=m[i+3];
|
89
|
+
e+=m[i+4]; f+=m[i+5]; g+=m[i+6]; h+=m[i+7];
|
90
|
+
mix(a,b,c,d,e,f,g,h);
|
91
|
+
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
92
|
+
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
93
|
+
}
|
94
|
+
}
|
95
|
+
else
|
96
|
+
{
|
97
|
+
/* fill in mm[] with messy stuff */
|
98
|
+
for (i=0; i<RANDSIZ4; i+=8)
|
99
|
+
{
|
100
|
+
mix(a,b,c,d,e,f,g,h);
|
101
|
+
m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
|
102
|
+
m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
isaac_rand4(ctx); /* fill in the first set of results */
|
107
|
+
ctx->randcnt=RANDSIZ4; /* prepare to use the first set of results */
|
108
|
+
}
|
109
|
+
|
110
|
+
|
111
|
+
#ifdef NEVER
|
112
|
+
#include <stdio.h>
|
113
|
+
|
114
|
+
int main()
|
115
|
+
{
|
116
|
+
ub4 i,j;
|
117
|
+
randctx4 ctx;
|
118
|
+
ctx.randa=ctx.randb=ctx.randc=(ub4)0;
|
119
|
+
for (i=0; i<RANDSIZ4; ++i) ctx.randrsl[i]=(ub4)0;
|
120
|
+
isaac_init4(&ctx, 1);
|
121
|
+
for (i=0; i<2; ++i)
|
122
|
+
{
|
123
|
+
isaac_rand4(&ctx);
|
124
|
+
for (j=0; j<RANDSIZ4; ++j)
|
125
|
+
{
|
126
|
+
printf("%.8lx",(long unsigned int)ctx.randrsl[j]);
|
127
|
+
if ((j&7)==7) printf("\n");
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}
|
131
|
+
#endif
|
data/ext/isaac/rand4.h
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
/*
|
2
|
+
------------------------------------------------------------------------------
|
3
|
+
rand4.h: rand.h specialized to RANDSIZL=4
|
4
|
+
------------------------------------------------------------------------------
|
5
|
+
*/
|
6
|
+
|
7
|
+
#include <stdint.h>
|
8
|
+
|
9
|
+
#include "rand.h"
|
10
|
+
|
11
|
+
#ifndef RAND4
|
12
|
+
#define RAND4
|
13
|
+
#define RANDSIZ4 (1<<4)
|
14
|
+
|
15
|
+
/* context of random number generator */
|
16
|
+
struct randctx4
|
17
|
+
{
|
18
|
+
ub4 randcnt;
|
19
|
+
ub4 randrsl[RANDSIZ4];
|
20
|
+
ub4 randmem[RANDSIZ4];
|
21
|
+
ub4 randa;
|
22
|
+
ub4 randb;
|
23
|
+
ub4 randc;
|
24
|
+
};
|
25
|
+
typedef struct randctx4 randctx4;
|
26
|
+
|
27
|
+
/*
|
28
|
+
------------------------------------------------------------------------------
|
29
|
+
If (flag==TRUE), then use the contents of randrsl[0..RANDSIZ4-1] as the seed.
|
30
|
+
------------------------------------------------------------------------------
|
31
|
+
*/
|
32
|
+
void isaac_init4(randctx4 *r, int flag);
|
33
|
+
|
34
|
+
void isaac_rand4(randctx4 *r);
|
35
|
+
|
36
|
+
|
37
|
+
/*
|
38
|
+
------------------------------------------------------------------------------
|
39
|
+
Call rand4(/o_ randctx4 *r _o/) to retrieve a single 32-bit random value
|
40
|
+
------------------------------------------------------------------------------
|
41
|
+
*/
|
42
|
+
#define rand4(r) \
|
43
|
+
(!(r)->randcnt-- ? \
|
44
|
+
(isaac_rand4(r), (r)->randcnt=RANDSIZ4-1, (r)->randrsl[(r)->randcnt]) : \
|
45
|
+
(r)->randrsl[(r)->randcnt])
|
46
|
+
|
47
|
+
#endif /* RAND4 */
|
48
|
+
|
49
|
+
|
data/test/test_isaac.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'isaac'
|
3
|
+
|
4
|
+
include PRNG
|
5
|
+
|
6
|
+
class TestIsaac < MiniTest::Unit::TestCase
|
7
|
+
SEED = (0..255).map {rand(2**32-1)}
|
8
|
+
# note that minitest supplies the seed to ruby's Kernel#rand
|
9
|
+
# use '--seed N' to select a particular seed
|
10
|
+
|
11
|
+
SEQ_1_2_3 = {
|
12
|
+
ISAAC4 => [
|
13
|
+
200253249, 3829869937, 4163837080, 3505347059, 4075830238,
|
14
|
+
2736331801, 3164829547, 410071848, 1780052116, 1192885451],
|
15
|
+
ISAAC => [
|
16
|
+
2356990817, 1396826555, 488165990, 3792500048, 3350490136,
|
17
|
+
3216315542, 2855747110, 2938836516, 2909213788, 1662784833]
|
18
|
+
}
|
19
|
+
|
20
|
+
CASES = [ISAAC4, ISAAC]
|
21
|
+
|
22
|
+
def setup
|
23
|
+
@rs = CASES.map {|cl| r=cl.new; r.srand SEED; r}
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_ranges
|
27
|
+
@rs.each do |r|
|
28
|
+
range = 0..1
|
29
|
+
range32 = 0..2**32-1
|
30
|
+
|
31
|
+
10.times do
|
32
|
+
assert_includes range, r.rand, r.class
|
33
|
+
assert_includes range32, r.rand32, r.class
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_repeatable
|
39
|
+
@rs.each do |r|
|
40
|
+
r2 = r.class.new
|
41
|
+
r2.srand SEED
|
42
|
+
10.times do
|
43
|
+
assert_equal(r.rand32, r2.rand32, r.class)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_predictable
|
49
|
+
@rs.each do |r|
|
50
|
+
r.srand [1,2,3]
|
51
|
+
assert_equal(SEQ_1_2_3[r.class], (0..9).map {r.rand32}, r.class)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_marshal
|
56
|
+
@rs.each do |r|
|
57
|
+
r2 = Marshal.load(Marshal.dump(r))
|
58
|
+
10.times do
|
59
|
+
assert_equal(r.rand32, r2.rand32, r.class)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
metadata
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: prng-isaac
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.5
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joel VanderWerf
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-04-22 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A pseudorandom number generator based on Bob Jenkins' ISAAC; useful for
|
14
|
+
both simulation and crypto.
|
15
|
+
email: vjoel@users.sourceforge.net
|
16
|
+
executables: []
|
17
|
+
extensions:
|
18
|
+
- ext/isaac/extconf.rb
|
19
|
+
extra_rdoc_files:
|
20
|
+
- RELEASE-NOTES
|
21
|
+
- README.md
|
22
|
+
- COPYING
|
23
|
+
files:
|
24
|
+
- RELEASE-NOTES
|
25
|
+
- README.md
|
26
|
+
- COPYING
|
27
|
+
- ext/isaac/extconf.rb
|
28
|
+
- ext/isaac/isaac.c
|
29
|
+
- ext/isaac/rand4.c
|
30
|
+
- ext/isaac/rand.c
|
31
|
+
- ext/isaac/rand4.h
|
32
|
+
- ext/isaac/rand.h
|
33
|
+
- ext/isaac/Makefile
|
34
|
+
- bench/bench.rb
|
35
|
+
- test/test_isaac.rb
|
36
|
+
homepage: https://github.com/vjoel/isaac
|
37
|
+
licenses: []
|
38
|
+
metadata: {}
|
39
|
+
post_install_message:
|
40
|
+
rdoc_options:
|
41
|
+
- --quiet
|
42
|
+
- --line-numbers
|
43
|
+
- --inline-source
|
44
|
+
- --title
|
45
|
+
- ISAAC
|
46
|
+
- --main
|
47
|
+
- README.md
|
48
|
+
require_paths:
|
49
|
+
- lib
|
50
|
+
- ext
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
requirements: []
|
62
|
+
rubyforge_project:
|
63
|
+
rubygems_version: 2.0.3
|
64
|
+
signing_key:
|
65
|
+
specification_version: 4
|
66
|
+
summary: ISAAC pseudorandom number generator
|
67
|
+
test_files:
|
68
|
+
- test/test_isaac.rb
|