Array#sample and Array#shuffle using SecureRandom
Encourages you to use SecureRandom more often. Don't use srand!
USAGE
$ gem install securerandom-array
$ irb
>> require 'securerandom/array'
>> [1,2,3].secure_shuffle # e.g. [1,3,2]
>> [1,2,3].secure_sample # e.g. 2
>> [1,2,3].secure_sample(random: Random.new(42)) # => 2
CODE
require 'securerandom'
class Array
  # Has a similar API like #shuffle, but uses SecureRandom
  # Delegates to original #shuffle if a Hash argument is given
  def secure_shuffle(o={})
    raise ArgumentError, 'wrong number of arguments (1 for 0)' unless o.is_a?(Hash)
    if random = o[:random]
      shuffle(random: random)
    else
       old = dup
      [*1..size].reverse_each.with_object([]){ |i, res|
        res << old.delete_at(SecureRandom.random_number(i))
      }
    end
  end
  # Has a similar API like #sample, but uses SecureRandom
  # Delegates to original #sample if a Hash argument is given
  def secure_sample(n=:single, o={})
    o, n = n, :single if n.is_a?(Hash)
    raise ArgumentError, 'wrong number of arguments (2 for 1)' unless o.is_a?(Hash)
    if random = o[:random]
      args = [{random: random}]
      args.unshift(n) unless n == :single
      sample(*args)
    else
      if n == :single
        self[SecureRandom.random_number(size)]
      else
        raise ArgumentError, 'negative sample number' if n < 0
        res = []
        old = dup
        n = size if n > size
        [*(size-n+1)..size].reverse_each.with_object([]){ |i, res|
          res << old.delete_at(SecureRandom.random_number(i))
        }
      end
    end
  end
endWritten by J-_-L
Related protips
2 Responses
Can you please publish this gem on Github?
over 1 year ago
·
Can't you just do:
[1,2,3].shuffle(random: SecureRandom)
over 1 year ago
·
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
 #Ruby 
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#