rubysl-securerandom 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2ff8c11aa9809bb98128b216ad032db00d45ce48
4
+ data.tar.gz: 3198625bdd325fbc434ddbfcfe23ecc90b73fde3
5
+ SHA512:
6
+ metadata.gz: bcfff7a007ad01f43da4e111ff1bd1f083866cbc980efbd17e197aefafff02f681948177b16052292d06a49f95d13d208609712c96355600e3f9122c3e0ec713
7
+ data.tar.gz: 2149708075a815621b504f9ba3abfebda5bd11bfb50b7fc89e83975274680c9cc16fce35a249f407fcd3fbb2e2ee31de1d327eb8bd176d5b741a3dde1691d224
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ language: ruby
2
+ env:
3
+ - RUBYLIB=lib
4
+ - RUBYLIB=
5
+ script: mspec spec
6
+ rvm:
7
+ - 2.0.0
8
+ - rbx-2.2.1
9
+ matrix:
10
+ exclude:
11
+ - rvm: 2.0.0
12
+ env: RUBYLIB=lib
13
+ - rvm: rbx-2.2.1
14
+ env: RUBYLIB=
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rubysl-securerandom.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2013, Brian Shirai
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ 3. Neither the name of the library nor the names of its contributors may be
13
+ used to endorse or promote products derived from this software without
14
+ specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT,
20
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Rubysl::Securerandom
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rubysl-securerandom'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rubysl-securerandom
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,2 @@
1
+ require "rubysl/securerandom/securerandom"
2
+ require "rubysl/securerandom/version"
@@ -0,0 +1,145 @@
1
+ # = Secure random number generator interface.
2
+ #
3
+ # This library is an interface for secure random number generator which is
4
+ # suitable for generating session key in HTTP cookies, etc.
5
+ #
6
+ # It supports following secure random number generators.
7
+ #
8
+ # * openssl
9
+ # * /dev/urandom
10
+ #
11
+ # == Example
12
+ #
13
+ # # random hexadecimal string.
14
+ # p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"
15
+ # p SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559"
16
+ # p SecureRandom.hex(11) #=> "6aca1b5c58e4863e6b81b8"
17
+ # p SecureRandom.hex(12) #=> "94b2fff3e7fd9b9c391a2306"
18
+ # p SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"
19
+ # ...
20
+ #
21
+ # # random base64 string.
22
+ # p SecureRandom.base64(10) #=> "EcmTPZwWRAozdA=="
23
+ # p SecureRandom.base64(10) #=> "9b0nsevdwNuM/w=="
24
+ # p SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg=="
25
+ # p SecureRandom.base64(11) #=> "l7XEiFja+8EKEtY="
26
+ # p SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
27
+ # p SecureRandom.base64(13) #=> "vKLJ0tXBHqQOuIcSIg=="
28
+ # ...
29
+ #
30
+ # # random binary string.
31
+ # p SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
32
+ # p SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
33
+ # ...
34
+
35
+ begin
36
+ require 'openssl'
37
+ rescue LoadError
38
+ end
39
+
40
+ module SecureRandom
41
+ # SecureRandom.random_bytes generates a random binary string.
42
+ #
43
+ # The argument n specifies the length of the result string.
44
+ #
45
+ # If n is not specified, 16 is assumed.
46
+ # It may be larger in future.
47
+ #
48
+ # If secure random number generator is not available,
49
+ # NotImplementedError is raised.
50
+ def self.random_bytes(n=nil)
51
+ n ||= 16
52
+ if defined? OpenSSL::Random
53
+ @pid = 0 if !defined?(@pid)
54
+ pid = $$
55
+ if @pid != pid
56
+ now = Time.now
57
+ ary = [now.to_i, now.usec, @pid, pid]
58
+ OpenSSL::Random.seed(ary.join('.'))
59
+ @pid = pid
60
+ end
61
+ return OpenSSL::Random.random_bytes(n)
62
+ end
63
+ if !defined?(@has_urandom) || @has_urandom
64
+ @has_urandom = false
65
+ flags = File::RDONLY
66
+ flags |= File::NONBLOCK if defined? File::NONBLOCK
67
+ flags |= File::NOCTTY if defined? File::NOCTTY
68
+ flags |= File::NOFOLLOW if defined? File::NOFOLLOW
69
+ begin
70
+ File.open("/dev/urandom", flags) {|f|
71
+ unless f.stat.chardev?
72
+ raise Errno::ENOENT
73
+ end
74
+ @has_urandom = true
75
+ ret = f.readpartial(n)
76
+ if ret.length != n
77
+ raise NotImplementedError, "Unexpected partial read from random device"
78
+ end
79
+ return ret
80
+ }
81
+ rescue Errno::ENOENT
82
+ raise NotImplementedError, "No random device"
83
+ end
84
+ end
85
+ raise NotImplementedError, "No random device"
86
+ end
87
+
88
+ # SecureRandom.hex generates a random hex string.
89
+ #
90
+ # The argument n specifies the length of the random length.
91
+ # The length of the result string is twice of n.
92
+ #
93
+ # If n is not specified, 16 is assumed.
94
+ # It may be larger in future.
95
+ #
96
+ # If secure random number generator is not available,
97
+ # NotImplementedError is raised.
98
+ def self.hex(n=nil)
99
+ random_bytes(n).unpack("H*")[0]
100
+ end
101
+
102
+ # SecureRandom.base64 generates a random base64 string.
103
+ #
104
+ # The argument n specifies the length of the random length.
105
+ # The length of the result string is about 4/3 of n.
106
+ #
107
+ # If n is not specified, 16 is assumed.
108
+ # It may be larger in future.
109
+ #
110
+ # If secure random number generator is not available,
111
+ # NotImplementedError is raised.
112
+ def self.base64(n=nil)
113
+ [random_bytes(n)].pack("m*").delete("\n")
114
+ end
115
+
116
+ # SecureRandom.random_number generates a random number.
117
+ #
118
+ # If an positive integer is given as n,
119
+ # SecureRandom.random_number returns an integer:
120
+ # 0 <= SecureRandom.random_number(n) < n.
121
+ #
122
+ # If 0 is given or an argument is not given,
123
+ # SecureRandom.random_number returns an float:
124
+ # 0.0 <= SecureRandom.random_number() < 1.0.
125
+ def self.random_number(n=0)
126
+ if 0 < n
127
+ hex = n.to_s(16)
128
+ hex = '0' + hex if (hex.length & 1) == 1
129
+ bin = [hex].pack("H*")
130
+ mask = bin[0]
131
+ mask |= mask >> 1
132
+ mask |= mask >> 2
133
+ mask |= mask >> 4
134
+ begin
135
+ rnd = SecureRandom.random_bytes(bin.length)
136
+ rnd[0] = (rnd[0] & mask).chr
137
+ end until rnd < bin
138
+ rnd.unpack("H*")[0].hex
139
+ else
140
+ # assumption: Float::MANT_DIG <= 64
141
+ i64 = SecureRandom.random_bytes(8).unpack("Q")[0]
142
+ Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG)
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,5 @@
1
+ module RubySL
2
+ module SecureRandom
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ require "rubysl/securerandom"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ require './lib/rubysl/securerandom/version'
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = "rubysl-securerandom"
6
+ spec.version = RubySL::SecureRandom::VERSION
7
+ spec.authors = ["Brian Shirai"]
8
+ spec.email = ["brixen@gmail.com"]
9
+ spec.description = %q{Ruby standard lib securerandom.}
10
+ spec.summary = %q{Ruby standard lib securerandom.}
11
+ spec.homepage = "https://github.com/rubysl/rubysl-securerandom"
12
+ spec.license = "BSD"
13
+
14
+ spec.files = `git ls-files`.split($/)
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.required_ruby_version = "~> 1.8.7"
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "mspec", "~> 1.5"
24
+ spec.add_development_dependency "rubysl-prettyprint", "~> 1.0"
25
+ end
@@ -0,0 +1,56 @@
1
+
2
+ ruby_version_is "1.8.7" do
3
+ require 'securerandom'
4
+
5
+ describe "SecureRandom.base64" do
6
+ it "generates a random base64 string out of specified number of random bytes" do
7
+ (16..128).each do |idx|
8
+ base64 = SecureRandom.base64(idx)
9
+ base64.should be_kind_of(String)
10
+ base64.length.should < 2 * idx
11
+ base64.should =~ /^[A-Za-z0-9\+\/]+={0,2}$/
12
+ end
13
+
14
+ base64 = SecureRandom.base64(16.5)
15
+ base64.should be_kind_of(String)
16
+ base64.length.should < 2 * 16
17
+ end
18
+
19
+ it "returns an empty string when argument is 0" do
20
+ SecureRandom.base64(0).should == ""
21
+ end
22
+
23
+ it "generates different base64 strings with subsequent invocations" do
24
+ # quick and dirty check, but good enough
25
+ values = []
26
+ 256.times do
27
+ base64 = SecureRandom.base64
28
+ # make sure the random values are not repeating
29
+ values.include?(base64).should == false
30
+ values << base64
31
+ end
32
+ end
33
+
34
+ it "generates a random base64 string out of 32 random bytes" do
35
+ SecureRandom.base64.should be_kind_of(String)
36
+ SecureRandom.base64.length.should < 32 * 2
37
+ end
38
+
39
+ it "treats nil agrument as default one and generates a random base64 string" do
40
+ SecureRandom.base64(nil).should be_kind_of(String)
41
+ SecureRandom.base64(nil).length.should < 32 * 2
42
+ end
43
+
44
+ it "raises ArgumentError on negative arguments" do
45
+ lambda {
46
+ SecureRandom.base64(-1)
47
+ }.should raise_error(ArgumentError)
48
+ end
49
+
50
+ it "tries to convert the passed argument to an Integer using #to_int" do
51
+ obj = mock("to_int")
52
+ obj.should_receive(:to_int).and_return(5)
53
+ SecureRandom.base64(obj).size.should < 10
54
+ end
55
+ end
56
+ end
data/spec/hex_spec.rb ADDED
@@ -0,0 +1,55 @@
1
+
2
+ ruby_version_is "1.8.7" do
3
+ require 'securerandom'
4
+
5
+ describe "SecureRandom.hex" do
6
+ it "generates a random hex string of length twice the specified argement" do
7
+ (1..64).each do |idx|
8
+ hex = SecureRandom.hex(idx)
9
+ hex.should be_kind_of(String)
10
+ hex.length.should == 2 * idx
11
+ end
12
+
13
+ base64 = SecureRandom.hex(5.5)
14
+ base64.should be_kind_of(String)
15
+ base64.length.should eql(10)
16
+ end
17
+
18
+ it "returns an empty string when argument is 0" do
19
+ SecureRandom.hex(0).should == ""
20
+ end
21
+
22
+ it "generates different hex strings with subsequent invocations" do
23
+ # quick and dirty check, but good enough
24
+ values = []
25
+ 256.times do
26
+ hex = SecureRandom.hex
27
+ # make sure the random values are not repeating
28
+ values.include?(hex).should == false
29
+ values << hex
30
+ end
31
+ end
32
+
33
+ it "generates a random hex string of length 32 if no argument is provided" do
34
+ SecureRandom.hex.should be_kind_of(String)
35
+ SecureRandom.hex.length.should == 32
36
+ end
37
+
38
+ it "treats nil agrument as default one and generates a random hex string of length 32" do
39
+ SecureRandom.hex(nil).should be_kind_of(String)
40
+ SecureRandom.hex(nil).length.should == 32
41
+ end
42
+
43
+ it "raises ArgumentError on negative arguments" do
44
+ lambda {
45
+ SecureRandom.hex(-1)
46
+ }.should raise_error(ArgumentError)
47
+ end
48
+
49
+ it "tries to convert the passed argument to an Integer using #to_int" do
50
+ obj = mock("to_int")
51
+ obj.should_receive(:to_int).and_return(5)
52
+ SecureRandom.hex(obj).size.should eql(10)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,51 @@
1
+
2
+ ruby_version_is "1.8.7" do
3
+ require 'securerandom'
4
+
5
+ describe "SecureRandom.random_bytes" do
6
+ it "generates a random binary string of length 16 if no argument is provided" do
7
+ bytes = SecureRandom.random_bytes
8
+ bytes.should be_kind_of(String)
9
+ bytes.length.should == 16
10
+ end
11
+
12
+ it "generates a random binary string of length 16 if argument is nil" do
13
+ bytes = SecureRandom.random_bytes(nil)
14
+ bytes.should be_kind_of(String)
15
+ bytes.length.should == 16
16
+ end
17
+
18
+ it "generates a random binary string of specified length" do
19
+ (1..64).each do |idx|
20
+ bytes = SecureRandom.random_bytes(idx)
21
+ bytes.should be_kind_of(String)
22
+ bytes.length.should == idx
23
+ end
24
+
25
+ SecureRandom.random_bytes(2.2).length.should eql(2)
26
+ end
27
+
28
+ it "generates different binary strings with subsequent invocations" do
29
+ # quick and dirty check, but good enough
30
+ values = []
31
+ 256.times do
32
+ val = SecureRandom.random_bytes
33
+ # make sure the random bytes are not repeating
34
+ values.include?(val).should == false
35
+ values << val
36
+ end
37
+ end
38
+
39
+ it "raises ArgumentError on negative arguments" do
40
+ lambda {
41
+ SecureRandom.random_bytes(-1)
42
+ }.should raise_error(ArgumentError)
43
+ end
44
+
45
+ it "tries to convert the passed argument to an Integer using #to_int" do
46
+ obj = mock("to_int")
47
+ obj.should_receive(:to_int).and_return(5)
48
+ SecureRandom.random_bytes(obj).size.should eql(5)
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,48 @@
1
+
2
+ ruby_version_is "1.8.7" do
3
+ require 'securerandom'
4
+
5
+ describe "SecureRandom.random_number" do
6
+ it "generates a random positive number smaller then the positive integer argument" do
7
+ (1..64).each do |idx|
8
+ num = SecureRandom.random_number(idx)
9
+ num.should be_kind_of(Fixnum)
10
+ (0 <= num).should == true
11
+ (num < idx).should == true
12
+ end
13
+ end
14
+
15
+ it "generates a random float number between 0.0 and 1.0 if no argument provided" do
16
+ 64.times do
17
+ num = SecureRandom.random_number
18
+ num.should be_kind_of(Float)
19
+ (0.0 <= num).should == true
20
+ (num < 1.0).should == true
21
+ end
22
+ end
23
+
24
+ it "generates a random float number between 0.0 and 1.0 if argument is negative" do
25
+ num = SecureRandom.random_number(-10)
26
+ num.should be_kind_of(Float)
27
+ (0.0 <= num).should == true
28
+ (num < 1.0).should == true
29
+ end
30
+
31
+ it "generates different float numbers with subsequent invocations" do
32
+ # quick and dirty check, but good enough
33
+ values = []
34
+ 256.times do
35
+ val = SecureRandom.random_number
36
+ # make sure the random values are not repeating
37
+ values.include?(val).should == false
38
+ values << val
39
+ end
40
+ end
41
+
42
+ it "raises ArgumentError if the argument is non-numeric" do
43
+ lambda {
44
+ SecureRandom.random_number(Object.new)
45
+ }.should raise_error(ArgumentError)
46
+ end
47
+ end
48
+ end
metadata ADDED
@@ -0,0 +1,119 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubysl-securerandom
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Brian Shirai
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.5'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.5'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubysl-prettyprint
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.0'
69
+ description: Ruby standard lib securerandom.
70
+ email:
71
+ - brixen@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - ".travis.yml"
78
+ - Gemfile
79
+ - LICENSE
80
+ - README.md
81
+ - Rakefile
82
+ - lib/rubysl/securerandom.rb
83
+ - lib/rubysl/securerandom/securerandom.rb
84
+ - lib/rubysl/securerandom/version.rb
85
+ - lib/securerandom.rb
86
+ - rubysl-securerandom.gemspec
87
+ - spec/base64_spec.rb
88
+ - spec/hex_spec.rb
89
+ - spec/random_bytes_spec.rb
90
+ - spec/random_number_spec.rb
91
+ homepage: https://github.com/rubysl/rubysl-securerandom
92
+ licenses:
93
+ - BSD
94
+ metadata: {}
95
+ post_install_message:
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.8.7
104
+ required_rubygems_version: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ requirements: []
110
+ rubyforge_project:
111
+ rubygems_version: 2.2.2
112
+ signing_key:
113
+ specification_version: 4
114
+ summary: Ruby standard lib securerandom.
115
+ test_files:
116
+ - spec/base64_spec.rb
117
+ - spec/hex_spec.rb
118
+ - spec/random_bytes_spec.rb
119
+ - spec/random_number_spec.rb