fibonacci_rng 0.3.0 → 0.4.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 +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: []
|