super_random 0.1.0 → 2.0.210126

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
- 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