[前][次][番号順一覧][スレッド一覧]

ruby-changes:48195

From: akr <ko1@a...>
Date: Sun, 22 Oct 2017 01:12:51 +0900 (JST)
Subject: [ruby-changes:48195] akr:r60309 (trunk): less random generations in Random::Formatter#choose.

akr	2017-10-22 01:12:46 +0900 (Sun, 22 Oct 2017)

  New Revision: 60309

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=60309

  Log:
    less random generations in Random::Formatter#choose.

  Modified files:
    trunk/lib/securerandom.rb
    trunk/test/test_securerandom.rb
Index: test/test_securerandom.rb
===================================================================
--- test/test_securerandom.rb	(revision 60308)
+++ test/test_securerandom.rb	(revision 60309)
@@ -144,9 +144,10 @@ end https://github.com/ruby/ruby/blob/trunk/test/test_securerandom.rb#L144
   end
 
   def test_alphanumeric
-    65.times do |idx|
-      an = @it.alphanumeric
-      assert_match(/^[0-9a-zA-Z]+$/, an)
+    65.times do |n|
+      an = @it.alphanumeric(n)
+      assert_match(/^[0-9a-zA-Z]*$/, an)
+      assert_equal(n, an.length)
     end
   end
 
Index: lib/securerandom.rb
===================================================================
--- lib/securerandom.rb	(revision 60308)
+++ lib/securerandom.rb	(revision 60309)
@@ -243,7 +243,31 @@ module Random::Formatter https://github.com/ruby/ruby/blob/trunk/lib/securerandom.rb#L243
   # +NotImplementedError+ is raised.
   private def choose(source, n)
     size = source.size
-    n.times.map {source[random_number(size)]}.join('')
+    m = 1
+    limit = size
+    while limit * size <= 0x100000000
+      limit *= size
+      m += 1
+    end
+    result = ''.dup
+    while m <= n
+      rs = random_number(limit)
+      is = rs.digits(size)
+      (m-is.length).times { is << 0 }
+      result << source.values_at(*is).join('')
+      n -= m
+    end
+    if 0 < n
+      rs = random_number(limit)
+      is = rs.digits(size)
+      if is.length < n
+        (n-is.length).times { is << 0 }
+      else
+        is.pop while n < is.length
+      end
+      result.concat source.values_at(*is).join('')
+    end
+    result
   end
 
   ALPHANUMERIC = [*'A'..'Z', *'a'..'z', *'0'..'9']

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]