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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9c8a1e946cc05b8a0f7ef15c0f9f332f7170c1a8
4
- data.tar.gz: 69703e8ba9a17e3abb5b1cfbd67a91da806e8f7f
3
+ metadata.gz: a508cef0fdf713686d64af287131073ad0bf5ad9
4
+ data.tar.gz: 767c9eee52ab193288b848ab9d4ef5090a80ec10
5
5
  SHA512:
6
- metadata.gz: 9b285d3413bb9e669ca12030af0050672de993c0d65cf188cd25102a02d07b5df08c3091d7bf7d2f216d4d0a2b520243c0172494d62109c6ddeb738d0cda27da
7
- data.tar.gz: 07d897637e993f0bb05088f8e336851e9f51177326dac0922de78b1bf63a09cef4e6af9cfe4c612a8dad4367b911e660f97a91340a5bb067f56097471792f9c7
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. This is meant to serve as an example of a lesser or poorly
5
- implemented random number generator. Until now, the linear congruential and
6
- middle squares generators have been picked on as poor, so I felt that a new
7
- contender was required. Proving that this is indeed a poor RNG is left as an
8
- exercise for the reader!
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
- ### Hashing
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
- ### Salting
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 some possible
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
- salt_string = FibonacciRng.new.hash_string
95
- salt_string = FibonacciRng.new(FibonacciRng.new_seed, 12).hash_string()
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.
@@ -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. Just try and prove that it sucks! ;-)"
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
 
@@ -2,5 +2,5 @@
2
2
 
3
3
  #The class of Fibonacci inspired random number generators.
4
4
  class FibonacciRng
5
- VERSION = "0.3.0"
5
+ VERSION = "0.4.0"
6
6
  end
data/lib/fibonacci_rng.rb CHANGED
@@ -25,10 +25,11 @@ class FibonacciRng
25
25
  old
26
26
  end
27
27
 
28
- CHOP = 0x1FFFFFFF
29
- BYTE = 0xFF
30
- WORD = 0xFFFF
31
- BASE = (CHOP+1).to_f
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(seed=FibonacciRng.new_seed, depth=8)
41
- fail "Invalid depth value (2..99)." unless (2..99) === depth
42
- @depth = depth
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
- (128*@depth).times do
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.3.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-16 00:00:00.000000000 Z
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. Just try and prove
98
- that it sucks! ;-)
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: []