rubysl-securerandom 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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