Module: SecureRandom
- Defined in:
- lib/securerandom.rb
Overview
Secure random number generator interface.
This library is an interface for secure random number generator which is suitable for generating session key in HTTP cookies, etc.
You can use this library in your application by requiring it:
require 'securerandom'
It supports following secure random number generators.
-
openssl
-
/dev/urandom
-
Win32
Examples
Hexadecimal string.
require 'securerandom'
p SecureRandom.hex(10) #=> "52750b30ffbc7de3b362"
p SecureRandom.hex(10) #=> "92b15d6c8dc4beb5f559"
p SecureRandom.hex(13) #=> "39b290146bea6ce975c37cfc23"
Base64 string.
p SecureRandom.base64(10) #=> "EcmTPZwWRAozdA=="
p SecureRandom.base64(10) #=> "KO1nIU+p9DKxGg=="
p SecureRandom.base64(12) #=> "7kJSM/MzBJI+75j8"
Binary string.
p SecureRandom.random_bytes(10) #=> "\016\t{\370g\310pbr\301"
p SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337"
Defined Under Namespace
Class Method Summary collapse
-
.base64(n = nil) ⇒ Object
SecureRandom.base64 generates a random base64 string.
- .gen_random(n) ⇒ Object
-
.hex(n = nil) ⇒ Object
SecureRandom.hex generates a random hexadecimal string.
-
.lastWin32ErrorMessage ⇒ Object
:nodoc:.
-
.random_bytes(n = nil) ⇒ Object
SecureRandom.random_bytes generates a random binary string.
-
.random_number(n = 0) ⇒ Object
SecureRandom.random_number generates a random number.
-
.urlsafe_base64(n = nil, padding = false) ⇒ Object
SecureRandom.urlsafe_base64 generates a random URL-safe base64 string.
-
.uuid ⇒ Object
SecureRandom.uuid generates a v4 random UUID (Universally Unique IDentifier).
Class Method Details
.base64(n = nil) ⇒ Object
SecureRandom.base64 generates a random base64 string.
The argument n specifies the length, in bytes, of the random number to be generated. The length of the result string is about 4/3 of n.
If n is not specified or is nil, 16 is assumed. It may be larger in future.
The result may contain A-Z, a-z, 0-9, “+”, “/” and “=”.
p SecureRandom.base64 #=> "/2BuBuLf3+WfSKyQbRcc/A=="
p SecureRandom.base64 #=> "6BbW0pxO0YENxn38HMUbcQ=="
If secure random number generator is not available, NotImplementedError is raised.
See RFC 3548 for the definition of base64.
193 194 195 |
# File 'lib/securerandom.rb', line 193 def self.base64(n=nil) [random_bytes(n)].pack("m*").delete("\n") end |
.gen_random(n) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/securerandom.rb', line 114 def self.gen_random(n) @pid = 0 unless defined?(@pid) pid = $$ unless @pid == pid now = Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond) ary = [now, @pid, pid] OpenSSL::Random.random_add(ary.join("").to_s, 0.0) @pid = pid end return OpenSSL::Random.random_bytes(n) end |
.hex(n = nil) ⇒ Object
SecureRandom.hex generates a random hexadecimal string.
The argument n specifies the length, in bytes, of the random number to be generated. The length of the resulting hexadecimal string is twice n.
If n is not specified or is nil, 16 is assumed. It may be larger in future.
The result may contain 0-9 and a-f.
p SecureRandom.hex #=> "eb693ec8252cd630102fd0d0fb7c3485"
p SecureRandom.hex #=> "91dc3bfb4de5b11d029d376634589b61"
If secure random number generator is not available, NotImplementedError is raised.
172 173 174 |
# File 'lib/securerandom.rb', line 172 def self.hex(n=nil) random_bytes(n).unpack("H*")[0] end |
.lastWin32ErrorMessage ⇒ Object
:nodoc:
130 131 132 133 |
# File 'lib/securerandom.rb', line 130 def self.lastWin32ErrorMessage # :nodoc: # for compatibility return Kernel32. end |
.random_bytes(n = nil) ⇒ Object
SecureRandom.random_bytes generates a random binary string.
The argument n specifies the length of the result string.
If n is not specified or is nil, 16 is assumed. It may be larger in future.
The result may contain any byte: “x00” - “xff”.
p SecureRandom.random_bytes #=> "\xD8\\\xE0\xF4\r\xB2\xFC*WM\xFF\x83\x18\xF45\xB6"
p SecureRandom.random_bytes #=> "m\xDC\xFC/\a\x00Uf\xB2\xB2P\xBD\xFF6S\x97"
If secure random number generator is not available, NotImplementedError is raised.
108 109 110 111 |
# File 'lib/securerandom.rb', line 108 def self.random_bytes(n=nil) n = n ? n.to_int : 16 gen_random(n) end |
.random_number(n = 0) ⇒ Object
SecureRandom.random_number generates a random number.
If a positive integer is given as n, SecureRandom.random_number returns an integer: 0 <= SecureRandom.random_number(n) < n.
p SecureRandom.random_number(100) #=> 15
p SecureRandom.random_number(100) #=> 88
If 0 is given or an argument is not given, SecureRandom.random_number returns a float: 0.0 <= SecureRandom.random_number() < 1.0.
p SecureRandom.random_number #=> 0.596506046187744
p SecureRandom.random_number #=> 0.350621695741409
247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/securerandom.rb', line 247 def self.random_number(n=0) if 0 < n if defined? OpenSSL::BN OpenSSL::BN.rand_range(n).to_i else hex = n.to_s(16) hex = '0' + hex if (hex.length & 1) == 1 bin = [hex].pack("H*") mask = bin[0].ord mask |= mask >> 1 mask |= mask >> 2 mask |= mask >> 4 begin rnd = SecureRandom.random_bytes(bin.length) rnd[0] = (rnd[0].ord & mask).chr end until rnd < bin rnd.unpack("H*")[0].hex end else # assumption: Float::MANT_DIG <= 64 if defined? OpenSSL::BN i64 = OpenSSL::BN.rand(64, -1).to_i else i64 = SecureRandom.random_bytes(8).unpack("Q")[0] end Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG) end end |
.urlsafe_base64(n = nil, padding = false) ⇒ Object
SecureRandom.urlsafe_base64 generates a random URL-safe base64 string.
The argument n specifies the length, in bytes, of the random number to be generated. The length of the result string is about 4/3 of n.
If n is not specified or is nil, 16 is assumed. It may be larger in future.
The boolean argument padding specifies the padding. If it is false or nil, padding is not generated. Otherwise padding is generated. By default, padding is not generated because “=” may be used as a URL delimiter.
The result may contain A-Z, a-z, 0-9, “-” and “_”. “=” is also used if padding is true.
p SecureRandom.urlsafe_base64 #=> "b4GOKm4pOYU_-BOXcrUGDg"
p SecureRandom.urlsafe_base64 #=> "UZLdOkzop70Ddx-IJR0ABg"
p SecureRandom.urlsafe_base64(nil, true) #=> "i0XQ-7gglIsHGV2_BNPrdQ=="
p SecureRandom.urlsafe_base64(nil, true) #=> "-M8rLhr7JEpJlqFGUMmOxg=="
If secure random number generator is not available, NotImplementedError is raised.
See RFC 3548 for the definition of URL-safe base64.
223 224 225 226 227 228 229 |
# File 'lib/securerandom.rb', line 223 def self.urlsafe_base64(n=nil, padding=false) s = [random_bytes(n)].pack("m*") s.delete!("\n") s.tr!("+/", "-_") s.delete!("=") unless padding s end |
.uuid ⇒ Object
SecureRandom.uuid generates a v4 random UUID (Universally Unique IDentifier).
p SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594"
p SecureRandom.uuid #=> "bad85eb9-0713-4da7-8d36-07a8e4b00eab"
p SecureRandom.uuid #=> "62936e70-1815-439b-bf89-8492855a7e6b"
The version 4 UUID is purely random (except the version). It doesn’t contain meaningful information such as MAC address, time, etc.
See RFC 4122 for details of UUID.
287 288 289 290 291 292 |
# File 'lib/securerandom.rb', line 287 def self.uuid ary = self.random_bytes(16).unpack("NnnnnN") ary[2] = (ary[2] & 0x0fff) | 0x4000 ary[3] = (ary[3] & 0x3fff) | 0x8000 "%08x-%04x-%04x-%04x-%04x%08x" % ary end |