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
end
Written by J-_-L
Related protips
2 Responses
![](https://coderwall-assets-0.s3.amazonaws.com/uploads/user/avatar/71429/33bb80f5bc11602f4e2f4c1ff338571e.jpeg)
Can you please publish this gem on Github?
over 1 year ago
·
![](https://coderwall-assets-0.s3.amazonaws.com/uploads/user/avatar/3125/0887991a8846577a6aa85433d6ab3ea2.png)
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#