super_random 0.1.0 → 2.0.210126

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 6b911b7150cf576f96ffcfd6180dc7bffc25e1e3
4
- data.tar.gz: 53a850f144d7908d762f3cf1dc1a77a7cae203ea
2
+ SHA256:
3
+ metadata.gz: 2480d12416526288677a0a9203d7e63ae666eb70b59fc792cc1a67bc2c35978a
4
+ data.tar.gz: 52d9c2e334770c1498f6afffc1bc967db38686a1d5098882f2b1290bbf5f1e60
5
5
  SHA512:
6
- metadata.gz: b7a29619d1473b51fe1d7d4a47c80facbe622b13f8df19da7ea458ef27a01e8a026adcf5d69d63fd7376a5d29118aa1d660e8cb98788e96ef522f2e95f77d2d3
7
- data.tar.gz: aa56f4060ffa1366fcf20ce96a38adabebda122bf0d036e61207d76494a1277991fedfe604f87f6a400d1ccb1e786b47fc990fa67c984dec0d0c922da969b286
6
+ metadata.gz: 3dcb0cb30658abd969e2930cc60bc9d0ff33bca7b4dc7ee0e418c43ba6f9815d52c7af4c21346320ff7941422e2ff8fbbb75a3e0453c9172edf3f05e5a0609ff
7
+ data.tar.gz: c0b24a58b9a236992b615a3bad666af0d5377575dabed3fd760cc3b2857904f9bec41ed3ee0f186c11820979c0bea50cf4f52de580ff6a576d3dc253a2644f43
@@ -0,0 +1,74 @@
1
+ # SuperRandom
2
+
3
+ * [VERSION 2.0.210126](https://github.com/carlosjhr64/super_random/releases)
4
+ * [github](https://github.com/carlosjhr64/super_random)
5
+ * [rubygems](https://rubygems.org/gems/super_random)
6
+
7
+ ## DESCRIPTION:
8
+
9
+ You can't get more random than random, but you can try really, really, really hard.
10
+
11
+ SuperRandom combines three online real random services to create a more perfect random byte.
12
+
13
+ ## INSTALL:
14
+
15
+ $ gem install super_random
16
+
17
+ ## SYNOPSIS:
18
+
19
+ ```ruby
20
+ require 'super_random'
21
+ super_random = SuperRandom.new
22
+
23
+ super_random.bytes(32) #~> ^\[\d+(, \d+){31}\]$
24
+ # Example:
25
+ # [142, 36, 107, 199, 1, 222, 69, 238, 130, 159, 236, 201, 199,
26
+ # 33, 237, 166, 189, 166, 95, 246, 111, 103, 113, 126, 27, 31,
27
+ # 244, 215, 200, 60, 255, 184]
28
+
29
+ sleep 1 # rate limit to be nice
30
+ super_random.hexadecimal(32) #~> ^\h{64}$
31
+ # Example:
32
+ # "3e0dffe42c08b849dc3c1290e7aa87dff4ad3037b29694136786a4db1e3efab8"
33
+
34
+ sleep 1
35
+ super_random.random_number(100.0) #~> ^\d{1,2}\.\d+$
36
+ # Example:
37
+ # 16.882225652425537
38
+
39
+ sleep 1
40
+ super_random.random_number(100) #~> ^\d{1,2}$
41
+ # Example:
42
+ # 85
43
+
44
+ # The "services" attribute gives the number of online services used.
45
+ # It's possible for a service to fail.
46
+ # Ultimately, SuperRandom uses SecureRandom as a failsafe.
47
+ super_random.services #=> 3
48
+ super_random.randomness #=> 3.0
49
+ ```
50
+
51
+ ## LICENSE:
52
+
53
+ (The MIT License)
54
+
55
+ Copyright (c) 2021 carlosjhr64
56
+
57
+ Permission is hereby granted, free of charge, to any person obtaining
58
+ a copy of this software and associated documentation files (the
59
+ 'Software'), to deal in the Software without restriction, including
60
+ without limitation the rights to use, copy, modify, merge, publish,
61
+ distribute, sublicense, and/or sell copies of the Software, and to
62
+ permit persons to whom the Software is furnished to do so, subject to
63
+ the following conditions:
64
+
65
+ The above copyright notice and this permission notice shall be
66
+ included in all copies or substantial portions of the Software.
67
+
68
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
69
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
70
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
71
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
72
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
73
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
74
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,13 +1,15 @@
1
1
  # Standard Libraries
2
2
  require 'timeout'
3
3
  require 'securerandom'
4
+ require 'net/http'
5
+ require 'json'
4
6
 
5
- # Helper Gem
6
- require 'random/online'
7
-
8
- # This Gem
9
- require 'super_random/version.rb'
10
- require 'super_random/super_random.rb'
7
+ class SuperRandom
8
+ VERSION = '2.0.210126'
9
+ # This Gem
10
+ require 'super_random/services'
11
+ require 'super_random/generator'
12
+ end
11
13
 
12
14
  # Requires:
13
15
  #`ruby`
@@ -0,0 +1,99 @@
1
+ class SuperRandom
2
+ DEFAULT_BYTES = 32
3
+
4
+ attr_accessor :first_timeout, :second_timeout, :nevermind
5
+ attr_reader :randomness, :services
6
+
7
+ def initialize
8
+ @first_timeout = 3
9
+ @second_timeout = 6
10
+ @nevermind = true
11
+ @randomness = 0.0
12
+ @services = 0
13
+ end
14
+
15
+ def bytes(n=DEFAULT_BYTES)
16
+ @randomness = 0.0
17
+ @services = 0
18
+
19
+ m = SuperRandom.services
20
+ a = Array.new m.length
21
+ t = Array.new m.length
22
+ m.each_with_index do |k,i|
23
+ t[i] = Thread.new{ a[i] = SuperRandom.send(k, n) }
24
+ end
25
+
26
+ begin
27
+ Timeout.timeout(@first_timeout) do
28
+ # Initially, would like to get them all.
29
+ t.each{_1.join}
30
+ end
31
+ rescue Timeout::Error
32
+ begin
33
+ Timeout.timeout(@second_timeout) do
34
+ # But at this point,
35
+ # would like to get at least one.
36
+ while a.all?{_1.nil?} and t.any?{_1.alive?}
37
+ Thread.pass
38
+ end
39
+ end
40
+ rescue Timeout::Error
41
+ # If we don't care that we got nothing, go on.
42
+ raise $! unless @nevermind
43
+ end
44
+ end
45
+
46
+ r = Array.new n
47
+ n.times{|i| r[i] = SecureRandom.random_number(256)}
48
+
49
+ a.each do |b|
50
+ next if b.nil?
51
+ l = b.length
52
+ @randomness += l.to_f/n.to_f
53
+ @services += 1
54
+ n.times{|i|r[i]=(r[i]+b[i%l])%256}
55
+ end
56
+
57
+ return r
58
+ end
59
+
60
+ def hexadecimal(n=DEFAULT_BYTES)
61
+ bytes(n).map{|i|i.to_s(16).rjust(2,'0')}.join
62
+ end
63
+
64
+ def random_number(scale=1.0, minbytes=6, maxbytes=[minbytes,DEFAULT_BYTES].max)
65
+ case scale
66
+ when Float
67
+ div = minbytes.times.inject(''){|s,i| s+'FF'}.to_i(16)
68
+ den = hexadecimal(minbytes).to_i(16)
69
+ return scale * den.to_f / div.to_f
70
+ when Integer
71
+ n = n0 = Math.log(scale, 256).ceil
72
+ e = e0 = 256**n
73
+ r = r0 = e0 % scale
74
+ while r > 0
75
+ n0 += 1
76
+ e0 *= 256
77
+ r0 = e0 % scale
78
+ if r0 <= r
79
+ # break if repeating pattern with big enough integer
80
+ break if r0 == r and n0 > minbytes
81
+ r,n,e = r0,n0,e0
82
+ end
83
+ break if n0 >= maxbytes
84
+ end
85
+ max = (e/scale)*scale
86
+ loop do
87
+ number = hexadecimal(n).to_i(16)
88
+ return number % scale if number < max
89
+ # On a relatively small chance that we're above max...
90
+ if @nevermind
91
+ warn "using SecureRandom.random_number(#{scale})"
92
+ return SecureRandom.random_number(scale)
93
+ end
94
+ end
95
+ end
96
+ raise "rand(scale Integer|Float)"
97
+ end
98
+ alias rand random_number
99
+ end
@@ -0,0 +1,45 @@
1
+ class SuperRandom
2
+ def self.services
3
+ [:quantum, :atmospheric, :hotbits]
4
+ end
5
+
6
+ # https://qrng.anu.edu.au/
7
+ # https://qrng.anu.edu.au/contact/api-documentation/
8
+ def self.quantum(n)
9
+ s = Net::HTTP.get(URI(
10
+ "https://qrng.anu.edu.au/API/jsonI.php?length=#{n}&type=uint8"))
11
+ a = JSON.parse(s)['data']
12
+ raise unless a.is_a?(Array) and a.length==n
13
+ raise unless a.all?{|i| i.is_a?(Integer) and i.between?(0,255)}
14
+ return a
15
+ rescue StandardError
16
+ warn "quantum (qrng.anu.edu.au) failed."
17
+ return nil
18
+ end
19
+
20
+ # https://www.random.org/
21
+ # https://www.random.org/integers/
22
+ def self.atmospheric(n)
23
+ s = Net::HTTP.get(URI(
24
+ "https://www.random.org/integers/?num=#{n}&min=0&max=255&col=1&base=10&format=plain&rnd=new"))
25
+ a = s.strip.split(/\s+/).map{|j|j.to_i}
26
+ raise unless a.length==n
27
+ raise unless a.all?{|i| i.between?(0,255)}
28
+ return a
29
+ rescue StandardError
30
+ warn "atmospheric (www.random.org) failed."
31
+ return nil
32
+ end
33
+
34
+ # https://www.fourmilab.ch/hotbits/
35
+ def self.hotbits(n, k='Pseudorandom')
36
+ s = Net::HTTP.get(URI(
37
+ "https://www.fourmilab.ch/cgi-bin/Hotbits.api?nbytes=#{n}&fmt=bin&apikey=#{k}"))
38
+ a = s.bytes
39
+ raise unless a.length==n
40
+ return a
41
+ rescue StandardError
42
+ warn "hotbits (www.fourmilab.ch) failed."
43
+ return nil
44
+ end
45
+ end
metadata CHANGED
@@ -1,57 +1,34 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: super_random
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 2.0.210126
5
5
  platform: ruby
6
6
  authors:
7
7
  - carlosjhr64
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-07 00:00:00.000000000 Z
12
- dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: realrand
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '2.0'
20
- - - ">="
21
- - !ruby/object:Gem::Version
22
- version: 2.0.2
23
- type: :runtime
24
- prerelease: false
25
- version_requirements: !ruby/object:Gem::Requirement
26
- requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: '2.0'
30
- - - ">="
31
- - !ruby/object:Gem::Version
32
- version: 2.0.2
11
+ date: 2021-01-26 00:00:00.000000000 Z
12
+ dependencies: []
33
13
  description: |
34
14
  You can't get more random than random, but you can try really, really, really hard.
35
15
 
36
- SuperRandom combines RealRand's three online real random services to create a more perfect random byte.
16
+ SuperRandom combines three online real random services to create a more perfect random byte.
37
17
  email: carlosjhr64@gmail.com
38
18
  executables: []
39
19
  extensions: []
40
- extra_rdoc_files:
41
- - README.rdoc
20
+ extra_rdoc_files: []
42
21
  files:
43
- - README.rdoc
22
+ - README.md
44
23
  - lib/super_random.rb
45
- - lib/super_random/super_random.rb
46
- - lib/super_random/version.rb
24
+ - lib/super_random/generator.rb
25
+ - lib/super_random/services.rb
47
26
  homepage: https://github.com/carlosjhr64/super_random
48
27
  licenses:
49
28
  - MIT
50
29
  metadata: {}
51
- post_install_message:
52
- rdoc_options:
53
- - "--main"
54
- - README.rdoc
30
+ post_install_message:
31
+ rdoc_options: []
55
32
  require_paths:
56
33
  - lib
57
34
  required_ruby_version: !ruby/object:Gem::Requirement
@@ -65,10 +42,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
65
42
  - !ruby/object:Gem::Version
66
43
  version: '0'
67
44
  requirements:
68
- - 'ruby: ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-linux]'
69
- rubyforge_project:
70
- rubygems_version: 2.5.2
71
- signing_key:
45
+ - 'ruby: ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]'
46
+ rubygems_version: 3.2.3
47
+ signing_key:
72
48
  specification_version: 4
73
49
  summary: You can't get more random than random, but you can try really, really, really
74
50
  hard.
@@ -1,58 +0,0 @@
1
- = super_random
2
-
3
- {<img src="https://badge.fury.io/rb/super_random.svg" alt="Gem Version" />}[http://badge.fury.io/rb/super_random]
4
-
5
- == DESCRIPTION:
6
-
7
- You can't get more random than random, but you can try really, really, really hard.
8
-
9
- SuperRandom combines RealRand's three online real random services to create a more perfect random byte.
10
-
11
- == SYNOPSIS:
12
-
13
- require 'super_random' #=> true
14
- super_random = SuperRandom.new # => #<SuperRandom:...
15
-
16
- # bytes returns 32 bytes by default (256 bits).
17
- super_random.bytes # => [123, 219, 128, ..., 248, 164, 100]
18
-
19
- # hexadecimal returns a 32 bytes hexadecimal by default.
20
- super_random.hexadecimal #=> "2ae...37b"
21
-
22
- # rand as the typical use
23
- super_random.rand #=> 0.16882225652425537
24
- super_random.rand(100) #=> 85
25
-
26
- # The "services" attribute gives the number of online services used.
27
- # It's possible for a service to fail.
28
- # Ultimately, SuperRandom uses SecureRandom as a failsafe.
29
- super_random.services #=> 3
30
-
31
- == INSTALL:
32
-
33
- $ sudo gem install super_random
34
-
35
- == LICENSE:
36
-
37
- (The MIT License)
38
-
39
- Copyright (c) 2014 carlosjhr64
40
-
41
- Permission is hereby granted, free of charge, to any person obtaining
42
- a copy of this software and associated documentation files (the
43
- 'Software'), to deal in the Software without restriction, including
44
- without limitation the rights to use, copy, modify, merge, publish,
45
- distribute, sublicense, and/or sell copies of the Software, and to
46
- permit persons to whom the Software is furnished to do so, subject to
47
- the following conditions:
48
-
49
- The above copyright notice and this permission notice shall be
50
- included in all copies or substantial portions of the Software.
51
-
52
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
53
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
54
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
55
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
56
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
57
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
58
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,77 +0,0 @@
1
- class SuperRandom
2
-
3
- def self.randbyte(r,s)
4
- return r.randbyte
5
- rescue Exception
6
- warn "RealRand's #{s} failed."
7
- return nil
8
- end
9
-
10
- attr_accessor :first_timeout, :second_timeout, :nevermind
11
- attr_reader :randomness, :services
12
-
13
- def initialize
14
- @first_timeout = 3
15
- @second_timeout = 6
16
- @nevermind = true
17
- @randomness = 0.0
18
- @services = 0
19
- end
20
-
21
- def bytes(n=32)
22
- @randomness = 0.0
23
- @services = 0
24
-
25
- r1 = RealRand::RandomOrg.new
26
- r2 = RealRand::EntropyPool.new
27
- r3 = RealRand::FourmiLab.new
28
-
29
- a1 = a2 = a3 = nil
30
-
31
- t1 = Thread.new{ a1 = SuperRandom.randbyte(r1,'RandomOrg')[0...n] }
32
- t2 = Thread.new{ a2 = SuperRandom.randbyte(r2,'EntropyPool')[0...n] }
33
- t3 = Thread.new{ a3 = SuperRandom.randbyte(r3,'FourmiLab')[0...n] }
34
-
35
- begin
36
- Timeout.timeout(@first_timeout) do
37
- # Initially, would like to get them all.
38
- t1.join and t2.join and t3.join
39
- end
40
- rescue Timeout::Error
41
- begin
42
- Timeout.timeout(@second_timeout) do
43
- # But at this point,
44
- # would like to get at least one.
45
- while a1.nil? and a2.nil? and a3.nil? and (t1.alive? or t2.alive? or t3.alive?)
46
- Thread.pass
47
- end
48
- end
49
- rescue Timeout::Error
50
- # If we don't care that we got nothing, go on.
51
- raise $! unless @nevermind
52
- end
53
- end
54
-
55
- a = n.times.inject([]){|b,i|b.push(SecureRandom.random_number(256))}
56
- [a1, a2, a3].each do |b|
57
- if b
58
- bl = b.length
59
- @randomness += bl.to_f/n.to_f
60
- @services += 1
61
- n.times{|i|a[i]=(a[i]+b[i%bl])%256}
62
- end
63
- end
64
-
65
- return a
66
- end
67
-
68
- def hexadecimal(n=32)
69
- bytes(n).map{|i|i.to_s(16).rjust(2,'0')}.join
70
- end
71
-
72
- def rand(m=nil, n=6)
73
- div = n.times.inject(''){|s,i| s+'FF'}.to_i(16).to_f
74
- r = hexadecimal(n).to_i(16).to_f / div
75
- m.nil? ? r : (m*r).to_i
76
- end
77
- end
@@ -1,3 +0,0 @@
1
- class SuperRandom
2
- VERSION = '0.1.0'
3
- end