Использование системного времени напрямую для получения случайных чисел - PullRequest
0 голосов
/ 08 января 2011

Мне пришлось вернуть случайный элемент из массива, поэтому я нашел этот заполнитель:

return codes[(int) (System.currentTimeMillis() % codes.length - 1)];

Теперь, когда я думаю об этом, я испытываю желание использовать его в реальном коде.В любом случае сеялка Random() использует системное время в качестве начального числа в большинстве языков, так почему бы не использовать это время напрямую?В качестве бонуса я свободен от беспокойства о неслучайных младших битах многих ГСЧ.Этот хак возвращается, чтобы укусить меня?(Язык является Java, если это актуально.)

Ответы [ 4 ]

2 голосов
/ 08 января 2011

Используйте встроенный java.util.Random. Пункт 47 из Effective Java (второе издание, стр. 215) приводит это как пример того, почему вы должны предпочесть стандартные библиотеки, а не свои собственные. Он начинается с объяснения того, что Math.abs(rnd.nextInt() % n - плохой подход, поскольку он не дает действительно случайного распределения, и вместо этого вам следует просто использовать rnd.nextInt(n). Далее говорится:

Написать версию метода random, которая исправляет эти три Вспышки, вы должны знать справедливо сумма о псевдослучайном числе генераторы, теория чисел и два дополнить арифметику.

...

Вам не нужно беспокоиться о деталях того, как nextInt(int) работает. Старший инженер, имеющий опыт работы с алгоритмами, потратил много времени на разработку, внедрение и тестирование этого метода, а затем показал его нескольким экспертам в этой области, чтобы убедиться, что он был правильным. Затем библиотека прошла бета-тестирование, была выпущена и широко использовалась миллионами программистов в течение большей части десятилетия. В этом методе еще не было обнаружено никаких недостатков, но если бы этот недостаток был обнаружен, он был бы исправлен в следующем обращении. Используя стандартную библиотеку, вы пользуетесь знаниями экспертов, которые ее написали, и опытом тех, кто использовал ее до вас.

Следует отметить, что, хотя в примере не используется тот же код, который вы предлагаете, это еще более верно для вашего примера. Взятие остатка от случайного целого числа искажает распределение, но, по крайней мере, оно имеет некоторую случайность. Просто изменить время - это еще хуже.

Вы недооцениваете сложность генераторов псевдослучайных чисел. Проблема с подходом, который вы предлагаете, состоит в том, что не только возможно, что распределение далеко не случайно, но, кроме того, оно будет действительно предсказуемым. Есть реальные примеры хакеров, использующих генераторы псевдослучайных чисел с предсказуемыми семенами для обмана в покере. Создание защищенного программного обеспечения (Viega and McGraw, 2002) содержит полную главу, в которой обсуждаются эти вопросы.

Вот хороший пример того, как плохие PRNG могут быть сломаны на практике. В 1999 году группа Software Security в Cigital обнаружила серьезный недостаток в реализации Техасского Холдема, который распространяется компанией ASF Software, Inc. Эксплойт позволил обманщику вычислить точную колоду, используемую для каждой руки в реальном времени. время. Это означает, что игрок, использующий эксплойт, знает карты в каждой руке оппонента, а также карты, составляющие флоп (карты, положенные на стол лицевой стороной вверх после раундов торговли). Мошенник может «знать, когда держать их и знать, когда их складывать» каждый раз. Злонамеренный злоумышленник может использовать этот эксплойт, чтобы обмануть невинных игроков на реальные деньги, чтобы не быть пойманным. (Стр. 238)

Вот два вопроса, которые обсуждают сложность случайности:

Это документ, которому всего несколько недель (но с очень неубедительным названием), описывающий, как вы можете атаковать алгоритм генерации сеансов PHP, используя предсказуемое начальное число PRNG:

2 голосов
/ 08 января 2011

Это ужасная идея!Даже не думай об этом!Последовательные вызовы этого доморощенного «генератора псевдослучайных чисел» будут коррелироваться настолько сильно, что вы могли бы просто использовать простой счетчик.(Который, в случае, если вы пропустили это, я не рекомендую.)

Отредактировано, чтобы добавить: Кстати, как вы его закодировали, индекс вашего массива будет иногда -1.Это тоже ужасная идея.

0 голосов
/ 08 января 2011

Как правило, существуют веские основания для разработки стандартных библиотечных классов.

Хотя было бы неплохо поэкспериментировать с написанием собственного кода для решения проблем в академической среде, в бизнес-среде лучше всего использовать проверенные и протестированные библиотеки и методы, которые с меньшей вероятностью могут вызвать нежелательное поведение в вашем приложении. 1003 *

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

0 голосов
/ 08 января 2011

Единственная причина, по которой я могу думать против этого: что, если системные часы всегда возвращают кратное 16 (это может произойти, например, на компьютерах с Windows XP), а ваш массив имеет длину 16?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...