diff --git a/ChangeLog b/ChangeLog index 275908aeb45d29..4cf1d9a56f519a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2007-06-08 Tanaka Akira + + * lib/secrand.rb: rename SecRand() to SecRand.random_number. + Fri Jun 8 16:34:20 2007 Tanaka Akira * ext/zlib/zlib.c (gzfile_s_open): use FilePathValue to support diff --git a/lib/secrand.rb b/lib/secrand.rb index b0d71c6c774e8d..5995500c7b2583 100644 --- a/lib/secrand.rb +++ b/lib/secrand.rb @@ -1,7 +1,7 @@ # = Secure random number generator interface. # # This library is a interface for secure random number generator which is -# suitable for HTTP cookies, etc. +# suitable for HTTP cookies, nonces, etc. # # It supports following secure random number generators. # @@ -16,6 +16,7 @@ # p SecRand.hex(11) #=> "6aca1b5c58e4863e6b81b8" # p SecRand.hex(12) #=> "94b2fff3e7fd9b9c391a2306" # p SecRand.hex(13) #=> "39b290146bea6ce975c37cfc23" +# ... # # # random base64 string. # p SecRand.base64(10) #=> "EcmTPZwWRAozdA==" @@ -94,32 +95,34 @@ def self.hex(n=nil) def self.base64(n=nil) [random_bytes(n)].pack("m*").delete("\n") end -end -# SecRand() generates a random number. -# -# If an positive integer is given as n, -# SecRand() returns an integer: 0 <= SecRand(n) < n. -# -# If 0 is given or an argument is not given, -# SecRand() returns an float: 0.0 <= SecRand() < 1.0. -def SecRand(n=0) - if 0 < n - 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 = SecRand.random_bytes(bin.length) - rnd[0] = (rnd[0].ord & mask).chr - end until rnd < bin - rnd.unpack("H*")[0].hex - else - # assumption: Float::MANT_DIG <= 64 - i64 = SecRand.random_bytes(8).unpack("Q")[0] - Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG) + # SecRand.random_number generates a random number. + # + # If an positive integer is given as n, + # SecRand.random_number returns an integer: + # 0 <= SecRand.random_number(n) < n. + # + # If 0 is given or an argument is not given, + # SecRand.random_number returns an float: + # 0.0 <= SecRand.random_number() < 1.0. + def self.random_number(n=0) + if 0 < n + 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 = SecRand.random_bytes(bin.length) + rnd[0] = (rnd[0].ord & mask).chr + end until rnd < bin + rnd.unpack("H*")[0].hex + else + # assumption: Float::MANT_DIG <= 64 + i64 = SecRand.random_bytes(8).unpack("Q")[0] + Math.ldexp(i64 >> (64-Float::MANT_DIG), -Float::MANT_DIG) + end end end