diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-10-21 15:21:26 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-10-21 15:21:26 +0000 |
commit | b867882a1c2a358bb7a46f84365c86a959d35240 (patch) | |
tree | 041ca5d0e77d08e53cd8a6c965f8ce3277fff65e | |
parent | cd381d8acca042d969c72da64ecd2088a6000a0d (diff) |
SecureRandom.alphanumeric implemented.
[ruby-core:68098] [Feature #10849] proposed by Andrew Butterfield.
SecureRandom.choose and SecureRandom.graph is not included.
(The implementation has SecureRandom.choose but it is private.)
I feel the method name, SecureRandom.choose, doesn't represent
the behavior well.
The actual use cases of SecureRandom.graph is not obvious.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60297 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | lib/securerandom.rb | 44 | ||||
-rw-r--r-- | test/test_securerandom.rb | 7 |
3 files changed, 53 insertions, 2 deletions
@@ -191,6 +191,10 @@ with all sufficient information, see the ChangeLog file or Redmine * http://blog.rubygems.org/2017/08/27/2.6.13-released.html * http://blog.rubygems.org/2017/10/09/unsafe-object-deserialization-vulnerability.html +* SecureRandom + * New methods: + * SecureRandom.alphanumeric + * Set * Add Set#to_s as alias to #inspect [Feature #13676] * Add Set#=== as alias to #include? [Feature #13801] diff --git a/lib/securerandom.rb b/lib/securerandom.rb index 2140a7e1fc..3ee5cbd4d6 100644 --- a/lib/securerandom.rb +++ b/lib/securerandom.rb @@ -222,10 +222,50 @@ module Random::Formatter "%08x-%04x-%04x-%04x-%04x%08x" % ary end - private - def gen_random(n) + private def gen_random(n) self.bytes(n) end + + # SecureRandom.choose generates a string that randomly draws from a + # source array of characters. + # + # The argument _source_ specifies the array of characters from which + # to generate the string. + # The argument _n_ specifies the length, in characters, of the string to be + # generated. + # + # The result may contain whatever characters are in the source array. + # + # p SecureRandom.choose([*'l'..'r']) #=> "lmrqpoonmmlqlron" + # p SecureRandom.choose([*'0'..'9'], 5) #=> "27309" + # + # If a secure random number generator is not available, + # +NotImplementedError+ is raised. + private def choose(source, n) + size = source.size + n.times.map {source[random_number(size)]}.join('') + end + + ALPHANUMERIC = [*'A'..'Z', *'a'..'z', *'0'..'9'] + # SecureRandom.alphanumeric generates a random alphanumeric string. + # + # The argument _n_ specifies the length, in characters, of the alphanumeric + # string to be generated. + # + # If _n_ is not specified or is nil, 16 is assumed. + # It may be larger in the future. + # + # The result may contain A-Z, a-z and 0-9. + # + # p SecureRandom.alphanumeric #=> "2BuBuLf3WfSKyQbR" + # p SecureRandom.alphanumeric(10) #=> "i6K93NdqiH" + # + # If a secure random number generator is not available, + # +NotImplementedError+ is raised. + def alphanumeric(n=nil) + n = 16 if n.nil? + choose(ALPHANUMERIC, n) + end end SecureRandom.extend(Random::Formatter) diff --git a/test/test_securerandom.rb b/test/test_securerandom.rb index f2cc7f553b..9b2c8a5e67 100644 --- a/test/test_securerandom.rb +++ b/test/test_securerandom.rb @@ -143,6 +143,13 @@ end assert_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/, uuid) end + def test_alphanumeric + 65.times do |idx| + an = @it.alphanumeric + assert_match(/^[0-9a-zA-Z]+$/, an) + end + end + def protect begin yield |