2016-03-01 3 views
-1

Я работаю на «доказуемо справедливом» сайте, где, скажем, участники X входят в рисунок, и нам нужно выбрать первый общий победитель, но тогда мы также идеально хотите выбрать N суб-победителей из общей суммы X.Как сгенерировать N случайных чисел из хеша SHA-256

(для любопытных, SHA-256 хэш станет Merkle корень дерева блока Bitcoin на предварительно заданное время)

Таким образом, учитывая SHA-256 хэш, как мы генерируем N случайных номера?

Я думаю, что знаю, как генерировать 1 случайное число (в пределах диапазона Fixnum рубина). Согласно этой статье: http://patshaughnessy.net/2014/1/9/how-big-is-a-bignum

Максимальное Fixnum целое число: 4611686018427387903

Давайте срывать первые буквы Y на SHA-256 хэш. Мы можем сгенерировать вместо того, чтобы полагаться на Merkle корень Bitcoin с:

d = Digest::SHA256.hexdigest('hello') 
> "2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824" 

Давайте первые 6 символов, или: 2cf24d

Конвертируйте по основанию 10:

'2cf24d'.to_i(16) 
> 2945613 

теперь имеют уникальный Fixnum на основе нашего корня merkle.

С участниками X, скажем, 17, мы решили победитель:

2945613 % 17 
> 6 

Так предположении, что все записи знают их порядок въезда, шестой абитуриент может доказать, что они должны быть победителем.

Теперь - какой был бы лучший способ аналогичного выбора N суб-победителей? Скажем, каждый из этих участников должен получить меньший, но все же несколько ценный приз.

+0

Это звучит как пыльная незаконная игра в азартные игры. Целесообразно, конечно, достаточно. –

+0

Crypto.SE: [Получение целого числа из байтов] (http://crypto.stackexchange.com/questions/8826/map-bytes-to-number), [Использование хэша как PRNG] (http: // crypto. stackexchange.com/questions/9076/using-a-hash-as-a-secure-prng). Это те части, теперь идут повеселиться, нарушая закон. Старайтесь не взломать вас до того, как вас арестуют. –

ответ

0

Почему бы просто не использовать хэш для семян?

[*1..17].shuffle(random: Random.new(0x2cf24d)) 
# => [15, 5, 9, 7, 14, 3, 16, 12, 2, 1, 17, 4, 6, 13, 11, 10, 8] 
[*1..17].shuffle(random: Random.new(0x2cf24d)) 
# => [15, 5, 9, 7, 14, 3, 16, 12, 2, 1, 17, 4, 6, 13, 11, 10, 8] 

EDIT: Это зависит от версии Ruby, хотя - я считаю, shuffle отличается от JRuby и МРТ, даже если Random производит ту же последовательность. Вы можете обойти это, выполнив сами shuffle. См. this question для получения более подробной информации. Это обходное решение работает для меня как в JRuby, так и в МРТ:

r = Random.new(0x2cf24d) 
[*1..17].sort_by { r.rand } 
# => [14, 11, 4, 10, 1, 3, 9, 13, 16, 17, 12, 5, 8, 2, 6, 7, 15] 
r = Random.new(0x2cf24d) 
[*1..17].sort_by { r.rand } 
# => [14, 11, 4, 10, 1, 3, 9, 13, 16, 17, 12, 5, 8, 2, 6, 7, 15] 
Смежные вопросы