Bug #4579 » securerandom_opensslfree.diff
| lib/securerandom.rb (working copy) | ||
|---|---|---|
| 
     # 
   | 
||
| 
     # It supports following secure random number generators. 
   | 
||
| 
     # 
   | 
||
| 
     # * openssl 
   | 
||
| 
     # * /dev/urandom 
   | 
||
| 
     # * Win32 
   | 
||
| 
     # 
   | 
||
| ... | ... | |
| 
     # p SecureRandom.random_bytes(10) #=> "\323U\030TO\234\357\020\a\337" 
   | 
||
| 
     # ... 
   | 
||
| 
     begin 
   | 
||
| 
       require 'openssl' 
   | 
||
| 
     rescue LoadError 
   | 
||
| 
     end 
   | 
||
| 
     module SecureRandom 
   | 
||
| 
       # SecureRandom.random_bytes generates a random binary string. 
   | 
||
| 
       # 
   | 
||
| ... | ... | |
| 
       def self.random_bytes(n=nil) 
   | 
||
| 
         n ||= 16 
   | 
||
| 
         if defined? OpenSSL::Random 
   | 
||
| 
           return OpenSSL::Random.random_bytes(n) 
   | 
||
| 
         end 
   | 
||
| 
         if !defined?(@has_urandom) || @has_urandom 
   | 
||
| 
           flags = File::RDONLY 
   | 
||
| 
           flags |= File::NONBLOCK if defined? File::NONBLOCK 
   | 
||
| test/test_securerandom.rb (revision 0) | ||
|---|---|---|
| 
     require 'test/unit' 
   | 
||
| 
     require 'securerandom' 
   | 
||
| 
     class TestSecureRandom < Test::Unit::TestCase 
   | 
||
| 
       def setup 
   | 
||
| 
         @it = SecureRandom 
   | 
||
| 
       end 
   | 
||
| 
       def test_s_random_bytes 
   | 
||
| 
         assert_equal(16, @it.random_bytes.size) 
   | 
||
| 
         assert_equal(Encoding::ASCII_8BIT, @it.random_bytes.encoding) 
   | 
||
| 
         65.times do |idx| 
   | 
||
| 
           assert_equal(idx, @it.random_bytes(idx).size) 
   | 
||
| 
         end 
   | 
||
| 
       end 
   | 
||
| 
       def test_s_hex 
   | 
||
| 
         assert_equal(16 * 2, @it.hex.size) 
   | 
||
| 
         33.times do |idx| 
   | 
||
| 
           assert_equal(idx * 2, @it.hex(idx).size) 
   | 
||
| 
           assert_equal(idx, @it.hex(idx).gsub(/(..)/) { [$1].pack('H*') }.size) 
   | 
||
| 
         end 
   | 
||
| 
       end 
   | 
||
| 
       def test_s_base64 
   | 
||
| 
         assert_equal(16, @it.base64.unpack('m*')[0].size) 
   | 
||
| 
         17.times do |idx| 
   | 
||
| 
           assert_equal(idx, @it.base64(idx).unpack('m*')[0].size) 
   | 
||
| 
         end 
   | 
||
| 
       end 
   | 
||
| 
       def test_s_urlsafe_base64 
   | 
||
| 
         safe = /[\n+\/]/ 
   | 
||
| 
         65.times do |idx| 
   | 
||
| 
           assert_not_match(safe, @it.urlsafe_base64(idx)) 
   | 
||
| 
         end 
   | 
||
| 
         # base64 can include unsafe byte 
   | 
||
| 
         10000.times do |idx| 
   | 
||
| 
           return if safe =~ @it.base64(idx) 
   | 
||
| 
         end 
   | 
||
| 
         flunk 
   | 
||
| 
       end 
   | 
||
| 
       def test_s_random_number_float 
   | 
||
| 
         100.times do 
   | 
||
| 
           v = @it.random_number 
   | 
||
| 
           assert(0.0 <= v && v < 1.0) 
   | 
||
| 
         end 
   | 
||
| 
       end 
   | 
||
| 
       def test_s_random_number_float_by_zero 
   | 
||
| 
         100.times do 
   | 
||
| 
           v = @it.random_number(0) 
   | 
||
| 
           assert(0.0 <= v && v < 1.0) 
   | 
||
| 
         end 
   | 
||
| 
       end 
   | 
||
| 
       def test_s_random_number_int 
   | 
||
| 
         100.times do |idx| 
   | 
||
| 
           next if idx.zero? 
   | 
||
| 
           v = @it.random_number(idx) 
   | 
||
| 
           assert(0 <= v && v < idx) 
   | 
||
| 
         end 
   | 
||
| 
       end 
   | 
||
| 
       def test_uuid 
   | 
||
| 
         assert_equal([8, 4, 4, 4, 8], @it.uuid.unpack('a8xa4xa4xa4xa8').map { |e| e.size }) 
   | 
||
| 
       end 
   | 
||
| 
       def protect 
   | 
||
| 
         begin 
   | 
||
| 
           yield 
   | 
||
| 
         rescue NotImplementedError 
   | 
||
| 
           # ignore 
   | 
||
| 
         end 
   | 
||
| 
       end 
   | 
||
| 
     end 
   | 
||