summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--benchmark/bm_securerandom.rb5
-rw-r--r--lib/securerandom.rb34
3 files changed, 32 insertions, 13 deletions
diff --git a/ChangeLog b/ChangeLog
index 14881a0a4d..7feb15a7fc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Fri Aug 8 01:53:37 2014 Masaki Matsushita <glass.saga@gmail.com>
+
+ * lib/securerandom.rb: use OpenSSL::BN for performance improvement.
+
+ * benchmark/bm_securerandom.rb: benchmark script.
+
Fri Aug 8 17:19:57 2014 SHIBATA Hiroshi <shibata.hiroshi@gmail.com>
* lib/open-uri.rb: remove needless condition for old ruby version.
diff --git a/benchmark/bm_securerandom.rb b/benchmark/bm_securerandom.rb
new file mode 100644
index 0000000000..a082ea6d5b
--- /dev/null
+++ b/benchmark/bm_securerandom.rb
@@ -0,0 +1,5 @@
+require "securerandom"
+
+20_0000.times do
+ SecureRandom.random_number(100)
+end
diff --git a/lib/securerandom.rb b/lib/securerandom.rb
index 3ff5075023..29368ee431 100644
--- a/lib/securerandom.rb
+++ b/lib/securerandom.rb
@@ -214,21 +214,29 @@ module SecureRandom
#
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 = SecureRandom.random_bytes(bin.length)
- rnd[0] = (rnd[0].ord & mask).chr
- end until rnd < bin
- rnd.unpack("H*")[0].hex
+ 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
- i64 = SecureRandom.random_bytes(8).unpack("Q")[0]
+ 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