fibonacci_rng 0.3.0 → 0.4.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 +67 -11
- data/fibonacci_rng.gemspec +1 -1
- data/lib/fibonacci_rng/version.rb +1 -1
- data/lib/fibonacci_rng.rb +26 -8
- data/tests/fibinacci_rng_tests.rb +31 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a508cef0fdf713686d64af287131073ad0bf5ad9
|
4
|
+
data.tar.gz: 767c9eee52ab193288b848ab9d4ef5090a80ec10
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 08463aeda003dc4e564565df6b6d1532a1d5320a21a9c3ede419a1df052a4ad129eb16770ebf955091e3ea9d69fb94af487ac9386c3f2a36f87cdfb2082feb2f
|
7
|
+
data.tar.gz: 9b7b32359d8d61a867f6a2f41ec9c29ef7cf221020393ab0321a38930f4140f3a14eaff947e83ce2b03da7a40c0c639e3aeb5dd0b2bb2d38723f21c61ab30f48
|
data/README.md
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
# FibonacciRng
|
2
2
|
|
3
3
|
This gem implements a random number generator inspired by the famous Fibonacci
|
4
|
-
number sequence.
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
number sequence. So far, this generator has performed quite well when compared
|
5
|
+
to the built-in Ruby random number generator when tested with:
|
6
|
+
|
7
|
+
* A chi-squared test
|
8
|
+
* An auto-correlation test
|
9
|
+
* An X/Y scatter graph test
|
10
|
+
|
11
|
+
At this time I lack the mathematical skill to go beyond these rudimentary
|
12
|
+
measures but they are enough to qualify this code for "light" duties.
|
13
|
+
|
14
|
+
Proving that this is indeed a good (or poor) RNG is left as an exercise for
|
15
|
+
the reader! Hopefully one with greater knowledge of statistics than I.
|
9
16
|
|
10
17
|
## Installation
|
11
18
|
|
@@ -39,12 +46,35 @@ also get a "random" generator of the default depth (8) and a randomized
|
|
39
46
|
seed. Here is an overview of the available options.
|
40
47
|
|
41
48
|
```ruby
|
49
|
+
#Method #1
|
42
50
|
@my_rng = FibonacciRng.new # Random seed, depth = 8
|
51
|
+
|
52
|
+
#Method #2
|
43
53
|
@my_rng = FibonacciRng.new(seed) # Specified seed, depth = 8
|
54
|
+
|
55
|
+
#Method #3
|
44
56
|
@my_rng = FibonacciRng.new(seed, 12) # Specified seed, depth = 12
|
57
|
+
|
58
|
+
#Method #4
|
45
59
|
@my_rng = FibonacciRng.new(FibonacciRng.new_seed, 12) # Random seed, depth = 12
|
46
60
|
|
47
61
|
```
|
62
|
+
In addition, keyword arguments are emulated (as of Version 0.3.1) so these
|
63
|
+
options also are available:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
#Method #5
|
67
|
+
@my_rng = FibonacciRng.new(seed: seed) # Specified seed, depth = 8
|
68
|
+
|
69
|
+
#Method #6
|
70
|
+
@my_rng = FibonacciRng.new(seed: seed, depth: 12) # Specified seed, depth = 12
|
71
|
+
|
72
|
+
#Method #7
|
73
|
+
@my_rng = FibonacciRng.new(depth: 12) # Random seed, depth = 12
|
74
|
+
```
|
75
|
+
Note: Mixing positional and keyword arguments will not, in general, work.
|
76
|
+
|
77
|
+
#### Generating Pseudo Random Data
|
48
78
|
|
49
79
|
To get some data out here are some options:
|
50
80
|
|
@@ -55,7 +85,7 @@ To get some data out here are some options:
|
|
55
85
|
@my_rng.float # A "random" float between 0 and less than 1.
|
56
86
|
```
|
57
87
|
|
58
|
-
and also available
|
88
|
+
and also available are these helpful methods:
|
59
89
|
|
60
90
|
```ruby
|
61
91
|
@my_rng.reseed(value) # Reseed the sequence with the new value.
|
@@ -68,7 +98,7 @@ If more than one stream of numbers is required, it is best to use multiple
|
|
68
98
|
instances of FibonacciRng objects rather than rely on one. This will help avoid
|
69
99
|
the two streams of data being correlated.
|
70
100
|
|
71
|
-
|
101
|
+
#### Hashing
|
72
102
|
|
73
103
|
As more as an experiment than anything else, it is also possible to use
|
74
104
|
the generator as a primitive hash generator. To do so, create a new
|
@@ -84,16 +114,34 @@ puts fib.hash_string
|
|
84
114
|
Note that the length of the hash string is a function of the depth of the
|
85
115
|
generator used to create it. This is about 5.5 characters per unit of depth.
|
86
116
|
|
87
|
-
|
117
|
+
#### Salting
|
88
118
|
|
89
119
|
Another (more practical) use for the Fibonacci generator is the creation of
|
90
|
-
salting strings for use in more capable hashing schemes. Here are
|
120
|
+
salting strings for use in more capable hashing schemes. Here are four possible
|
91
121
|
ways that this can be done:
|
92
122
|
|
93
123
|
```ruby
|
94
|
-
|
95
|
-
salt_string = FibonacciRng.new
|
124
|
+
#Method #1
|
125
|
+
salt_string = FibonacciRng.new.hash_string #Thread safe.
|
126
|
+
|
127
|
+
#Method #2
|
128
|
+
salt_string = FibonacciRng.new(depth: 12).hash_string #Thread safe.
|
129
|
+
|
130
|
+
#Method #3
|
131
|
+
Thread.current[:salter] = FibonacciRng.new #Need a separate generator for each thread.
|
132
|
+
# Much intervening code omitted.
|
133
|
+
salter = Thread.current[:salter]
|
134
|
+
salter << Time.now.to_s # Note that unique time values are NOT needed.
|
135
|
+
salt_string = salter.hash_string
|
136
|
+
|
137
|
+
#Method #4
|
138
|
+
Thread.current[:salter] = FibonacciRng.new #Need a separate generator for each thread.
|
139
|
+
# Much intervening code omitted.
|
140
|
+
salter = Thread.current[:salter]
|
141
|
+
salter.spin
|
142
|
+
salt_string = salter.hash_string
|
96
143
|
```
|
144
|
+
|
97
145
|
Each time any of these is run, a different salt string will be generated.
|
98
146
|
|
99
147
|
## Contributing
|
@@ -103,3 +151,11 @@ Each time any of these is run, a different salt string will be generated.
|
|
103
151
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
104
152
|
4. Push to the branch (`git push origin my-new-feature`)
|
105
153
|
5. Create new Pull Request
|
154
|
+
|
155
|
+
#### Plan B
|
156
|
+
|
157
|
+
Go to the GitHub repository and raise an issue calling attention to some
|
158
|
+
aspect that could use some TLC or a suggestion or an idea. Apply labels
|
159
|
+
to the issue that match the point you are trying to make. Then follow
|
160
|
+
your issue and keep up-to-date as it is worked on. All input are greatly
|
161
|
+
appreciated.
|
data/fibonacci_rng.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Peter Camilleri"]
|
10
10
|
spec.email = ["peter.c.camilleri@gmail.com"]
|
11
11
|
spec.homepage = "http://teuthida-technologies.com/"
|
12
|
-
spec.description = "A Fibonacci inspired pseudo random number generator.
|
12
|
+
spec.description = "A Fibonacci inspired pseudo random number generator. Suitable for light duties."
|
13
13
|
spec.summary = "A Fibonacci inspired pseudo random number generator."
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/lib/fibonacci_rng.rb
CHANGED
@@ -25,10 +25,11 @@ class FibonacciRng
|
|
25
25
|
old
|
26
26
|
end
|
27
27
|
|
28
|
-
CHOP
|
29
|
-
BYTE
|
30
|
-
WORD
|
31
|
-
BASE
|
28
|
+
CHOP = 0x1FFFFFFF
|
29
|
+
BYTE = 0xFF
|
30
|
+
WORD = 0xFFFF
|
31
|
+
BASE = (CHOP+1).to_f
|
32
|
+
DEPTHS = 2..99
|
32
33
|
|
33
34
|
#The depth of the Fibonacci array.
|
34
35
|
attr_reader :depth
|
@@ -37,9 +38,26 @@ class FibonacciRng
|
|
37
38
|
attr_reader :seed
|
38
39
|
|
39
40
|
#Initialize the PRN generator
|
40
|
-
def initialize(
|
41
|
-
|
42
|
-
|
41
|
+
def initialize(arg_a=nil, arg_b=nil)
|
42
|
+
#Extract the parameters.
|
43
|
+
if arg_a.is_a?(Hash)
|
44
|
+
seed = arg_a[:seed]
|
45
|
+
@depth = arg_a[:depth]
|
46
|
+
else
|
47
|
+
seed = arg_a
|
48
|
+
@depth = arg_b
|
49
|
+
end
|
50
|
+
|
51
|
+
#Set up the default parameters if needed.
|
52
|
+
seed ||= FibonacciRng.new_seed
|
53
|
+
@depth ||= 8
|
54
|
+
|
55
|
+
#Validate the depth.
|
56
|
+
unless DEPTHS === depth
|
57
|
+
fail "Invalid depth value #{depth}. Allowed values are #{DEPTHS}"
|
58
|
+
end
|
59
|
+
|
60
|
+
#Build the generator.
|
43
61
|
srand(seed)
|
44
62
|
end
|
45
63
|
|
@@ -144,7 +162,7 @@ class FibonacciRng
|
|
144
162
|
|
145
163
|
#Do the work of reseeding the PRNG
|
146
164
|
def do_reseed(indxsrc, seedsrc)
|
147
|
-
(
|
165
|
+
(32*@depth+768).times do
|
148
166
|
@buffer[indxsrc.next] += seedsrc.next
|
149
167
|
do_spin
|
150
168
|
end
|
@@ -11,6 +11,37 @@ class FibonacciRngTester < Minitest::Test
|
|
11
11
|
#Track mini-test progress.
|
12
12
|
include MinitestVisible
|
13
13
|
|
14
|
+
def test_how_we_build_generators
|
15
|
+
gen = FibonacciRng.new
|
16
|
+
assert_equal(8, gen.depth)
|
17
|
+
assert_equal(String, gen.seed.class)
|
18
|
+
|
19
|
+
gen = FibonacciRng.new('seed')
|
20
|
+
assert_equal(8, gen.depth)
|
21
|
+
assert_equal('seed', gen.seed)
|
22
|
+
|
23
|
+
gen = FibonacciRng.new('seed', 12)
|
24
|
+
assert_equal(12, gen.depth)
|
25
|
+
assert_equal('seed', gen.seed)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_building_with_keywords
|
29
|
+
gen = FibonacciRng.new(seed: 'seed')
|
30
|
+
assert_equal(8, gen.depth)
|
31
|
+
assert_equal('seed', gen.seed)
|
32
|
+
|
33
|
+
gen = FibonacciRng.new(depth: 12)
|
34
|
+
assert_equal(12, gen.depth)
|
35
|
+
assert_equal(String, gen.seed.class)
|
36
|
+
|
37
|
+
gen = FibonacciRng.new(seed: 'seed', depth: 12)
|
38
|
+
assert_equal(12, gen.depth)
|
39
|
+
assert_equal('seed', gen.seed)
|
40
|
+
|
41
|
+
gen = FibonacciRng.new(depth: 12, seed: 'seed')
|
42
|
+
assert_equal(12, gen.depth)
|
43
|
+
assert_equal('seed', gen.seed)
|
44
|
+
end
|
14
45
|
|
15
46
|
def test_that_rejects_bad_parms
|
16
47
|
assert_raises { FibonacciRng.new('seed', 1) }
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fibonacci_rng
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Peter Camilleri
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-03-
|
11
|
+
date: 2016-03-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: minitest_visible
|
@@ -94,8 +94,8 @@ dependencies:
|
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 4.0.1
|
97
|
-
description: A Fibonacci inspired pseudo random number generator.
|
98
|
-
|
97
|
+
description: A Fibonacci inspired pseudo random number generator. Suitable for light
|
98
|
+
duties.
|
99
99
|
email:
|
100
100
|
- peter.c.camilleri@gmail.com
|
101
101
|
executables: []
|