Array # sample e Array # shuffle usando SecureRandom

Encoraja você a usar SecureRandom com mais frequência. Não use srand !

USO

$ 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

CÓDIGO

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