Генерация случайных чисел с помощью Random.org

    Кто пытается арифметическими методами генерировать случайные числа, тот, конечно, живет во грехе.
    — Джон фон Нейман

    Есть такой хороший сервис random.org, который уже не раз упоминался на хабре. Основная задача сайта — генерация случайных чисел с использованием атмосферных шумов. На том же сайте можно найти результаты тестов и сравнения случайных и псевдослучайных генераторов с объяснениями что лучше и почему. В данной статье описывается простенькая библиотека для использования API сайта.

    Random.org


    На Random.org очень много полезных функций, которые используют генерацию случайных чисел: бросание монеты, кубиков, тасование карт, получение лотерейной комбинации, генерация звуков, битмапов и многое другое. Также есть кастомная генерация за заданным распределением. В принципе, все это не сложно, но интересен тот факт, что генерация происходит с использованием атмосферных шумов и это каким-то магическим образом позволяет получить лучший рандом чем Random.nextInt(). Тут то я подумал, что неплохо бы иметь в запасе библиотеку с таким API и решил её написать.

    Поиск


    Перед тем как писать, нужно поискать, может кто-нибудь уже делал такое. Да. Делал.
    • Simple Random.Org Java Api — простая либа с методом для генерации целых чисел, но тянет зависимость Apache HTTP Client, аж целых 658 килобайт.
    • Java TRNG client — тут уже все серьезнее. 40 килобайт и генерация чисел с помощью двух(!) сайтов. Да, недостаток в том, что либа создавалась для криптографии, потому там оперирование битами, байтами и вообще все сложно.

    В общем, я решил написать свою.

    API


    Random.org предоставляет примитивное HTTP GET API, впрочем ничего большего не нужно. Есть всего 4 типа операций.

    Integer Generator

    Генерирует случайные целые числа в заданном диапазоне. Например, так выглядит запрос на бросание двух кубиков:
    http://www.random.org/integers/?num=2&min=1&max=6&col=1&base=10&format=plain&rnd=new

    Sequence Generator

    Генерирует последовательность со всеми уникальными целыми числами в заданном диапазоне. По сути то, что делает Collections.shuffle(). Например, так выглядит запрос на перемешивания колоды карт:
    http://www.random.org/sequences/?min=1&max=52&col=1&format=plain&rnd=new

    String Generator

    Генерирует случайную строку заданного размера с возможностью выбора набора символов (цифры, ловер кейс, аппер кейс). Вот так, например, можно сгенерить ник своему персонажу пароль:
    http://www.random.org/strings/?num=1&len=12&digits=on&upperalpha=on&loweralpha=on&unique=on&format=plain&rnd=new

    Quota Checker

    Ну и как вы уже поняли, все это не бесплатно. Хотя не, дают миллион бесплатных бит в сутки. Этого более чем достаточно. А для того, чтобы узнать сколько осталось можно по следующей ссылке:
    http://www.random.org/quota/?format=plain
    Если вы кликали на три предыдущие ссылки, то вы уже потратили ~1500 бит.

    Ошибки

    В случае успеха генерации, сервер возвращает код 200, неудачи — код 503. Вот и все ошибки.

    Для этого API была написана библиотека из пяти классов на Java, в котором вызов всех вышеописанных методов в простой и понятной форме.
    // бросаем кубики
    IntegerGenerator ig = new IntegerGenerator();
    ig.generate(1, 6, 2);
    // тасуем карты
    SequenceGenerator sg = new SequenceGenerator();
    sg.generate(1, 52);
    // новый пароль
    StringGenerator strg = new StringGenerator();
    strg.generate(12, 1, true, true, true, true);
    // сколько бит осталось
    QuotaChecker qc = new QuotaChecker();
    qc.quota();
    


    Вроде и все. На github можете посмотреть исходники и скачать либу с оригинальным названием randomorg (6 килобайт).
    Поделиться публикацией

    Комментарии 82

      –2
      А в чем заключается преимущество этого сервиса? Более рандомный рандом?
        +16
        Да, не псевдо-, а настоящий рандом
          +3
          Сотня людей одновременно кубик бросают?
            +2
            Буду всегда читать сначала статью, а потом каменты… не наоборот, обещаю…
              +1
              А мне это показалось довольно забавным :)
              0
              Ага, сотню честных кубиков :)
                0
                Вы только что трудоустроили целую деревню в Бангладеше.
              0
              В неком смысле — да. Это уже не псевдослучайный генератор, а полностью случайный, так как участвуют непредсказуемые силы природы в его действии. Зачем подобные вещи смертным? Честно — не знаю, надеюсь придут понимающие люди и просветят =)
                +1
                Да. Посмотрите этот линк random.org/analysis
                  +19
                  Наглядно для тех, кому лень по ссылке заходить:

                  PHP rand() on Microsoft Windows
                  image

                  RANDOM.ORG
                  image

                  Тут разница очевидна.
                    –1
                    Чтобы разница уж точно была очевидна, нагляднее строить гистограмму и рисовать для сравнения соответствующую гауссиану или распределение Пуассона (смотря что за шум у нас там).
                      +3
                      Ничего в жизни не видел нагляднее, чем картинки выше. Уж точно не гистограмма гаустиана и пуассона, тут даже не надо тервера знать.
                      0
                      Подозреваю, если первый рандом получить несколько раз (можно даже рандомное количество раз), а затем применить к этому множеству некую функцию (например, простейший вариант: перемножить), то можно получить нечто близкое ко второму.
                        +6
                        Подозреваю, что вы ошибаетесь.

                        Ну, или приведите конкретный пример.
                          0
                          Возможно, в данном случае ошибаюсь (не знаю, как сгенерировать такую картинку).

                          Но я к чему веду… Имея «плохой» рандом можно получить «хороший». В пример можно привести возведение в «плохую» степень числа по модулю простого числа. Взгляните на этот пример. Здесь образуется псевдослучайная последовательность, не поддающаяся ни каким закономерностям. При этом, данная особенность используется в криптографических алгоритмах благодаря сложности вычисления обратной функции. Да, псевдослучайная, ну и что?
                            +2
                            Возводить в степень нужно, конечно же, не обычное число, а, так называемый, первообразный корень модуля. В примере выше, 3 — первообразный корень 17.

                            В общем, имея некие навыки в «матане», можно генерировать такие псевдослучайные числа, которые не поддаются никаким закономерностям.
                              +4
                              Фиг поймешь этот хабр. Если я не прав, приведите аргументы, подтверждающие это. Минусовать по причине «я не знаком с темой» не очень достойно хаброюзера.
                                0
                                закономерности все равно будут, но куда более сложные и не очевидные. +Это будет во много раз больше нагружать железо.
                                p.s. не минусовал вас
                                  +1
                                  Пускай нагружает. Это намного быстрее, чем ждать ответа от стороннего веб сервиса.
                                    0
                                    Ну в серьёзном проекте никто не будет использовать сторонний веб-сервис.
                                    Например, разработчики покерного софта (PokerStars там всякие, как самый известный привожу в пример), исключают псевдослучайность на своих серверах, собирая и применяя для генерации случайных чисел различные действия пользователя клиентской части софта, например, движения мышки на компе и т.п.
                                      0
                                      >>например, движения мышки на компе и т.п.

                                      Сомнительно. Откуда инфа? Зачем такие сложности если есть апаратные дешевые решения?
                                        0
                                        Это очевидно, что доверять какому-то левому сервису — неправильно.
                                        (кстати, ваш ник отражает принадлежность к разработке формата fb3?)
                                    +1
                                    Кнут, глава 3, «Случайные числа».
                                    Вкратце: без источника энтропии числа рано или поздно начнут повторяться.
                                      +1
                                      Да, но для псевдо случайных чисел период повторений настолько огромен, что это «псевдо» не должны быть проблемой.
                                        0
                                        Даже википедия говорит, что это не единственная проблема ГПСЧ, а еще есть неудачные реализации, криворукие маинтейнеры и особо удачные наборы входных данных.
                                        Нельзя быть слишком параноиком.
                              0
                              Лично я генерил такую картинку в firefox (canvas + Math.random), у меня получилось более похоже на вторую
                                +5
                                <?php
                                // Requires the GD Library
                                header("Content-type: image/png");
                                $im = imagecreatetruecolor(2120, 2120)
                                    or die("Cannot Initialize new GD image stream");
                                $white = imagecolorallocate($im, 255, 255, 255);
                                for ($y=0; $y<2120; $y++) {
                                    for ($x=0; $x<2120; $x++) {
                                        if (rand(0,1) === 1) {
                                            imagesetpixel($im, $x, $y, $white);
                                        }
                                    }
                                }		
                                imagepng($im);
                                imagedestroy($im);
                                

                                Microsoft Windows [Version 6.1.7601]
                                PHP 5.3.8-ZS5.5.0 (cli) (built: Aug 24 2011 15:25:45)
                                Windows7 + PGP 5.3.8
                                  0
                                  Почему именно 2120? Возможно, что с таким сдвигом тенденция не просматривается.
                                  В сравнении просто подобрана «удачная» картинка для PHP, попробуйте с такой же шириной картинки.
                                    +1
                                    Уже не помню, почему настолько большую сделал. Делал и 512, но тоже не получилось той же картинки. Вот вам сейчас сгенерировал 512×512 (картинка всегда меняется по F5):
                                  –1
                                  Хм… Действительно, проверил для явы


                                  public static void main(String[] args) throws IOException {
                                  int height = 512;
                                  int weight = 512;
                                  BufferedImage image = new BufferedImage(weight, height, BufferedImage.TYPE_INT_RGB);
                                  for (int x = 0 ; x < weight; x++) {
                                  for (int y = 0; y < height; y++) {
                                  image.setRGB(x, y, new Random().nextBoolean() ? Color.white.getRGB() : Color.black.getRGB());
                                  }
                                  }

                                  ImageIO.write(image, "jpg", new File("c:/randomCheck.jpg"));
                                  }
                                    +2
                                    В вот если использовать один и тот же объект картинка получается гораздо лучше


                                    public static void main(String[] args) throws IOException {
                                    Random r = new Random();
                                    int height = 512;
                                    int weight = 512;
                                    BufferedImage image = new BufferedImage(weight, height, BufferedImage.TYPE_INT_RGB);
                                    for (int x = 0; x < weight; x++) {
                                    for (int y = 0; y < height; y++) {
                                    image.setRGB(x, y, r.nextBoolean()? Color.white.getRGB(): Color.black.getRGB());
                                    }
                                    }

                                    ImageIO.write(image, «jpg», new File(«c:/randomCheck.jpg»));
                                    }

                                    Так что вполне себе нормальная случайность =).
                                    +1
                                    Ну и не так уж и очевидна (тоже PHP):


                                    function make_seed() {
                                    	list($usec, $sec) = explode(' ', microtime());
                                    	return (float) $sec + ((float) $usec * 100000);
                                    }
                                    mt_srand(make_seed());
                                    $size=512;
                                    $image = imagecreatetruecolor($size,$size);
                                    $black = imagecolorallocate ($image, 0,0,0 );
                                    $white = imagecolorallocate ($image, 255,255,255 );
                                    for ($x = 0; $x<$size; $x++) {
                                    	for ($y = 0; $y<$size; $y++) {
                                    		imagesetpixel($image,$x,$y,mt_rand(0,1)?$black:$white);
                                    	}	
                                    }
                                    header ('Content-Type: image/png');
                                    imagepng($image);
                                    


                                    Я согласен, что со встроенным генератором лотерейное ПО лучше не писать, но и совсем уж атавизмами типа функции rand() козырять тоже не стоит.
                                  +1
                                  Более рандомный относительно чего? Мейнстрим рандомы нынче псевдо-рандомны, т.е. по сути не являются рандомными и в теории их можно предсказывать.
                                    +2
                                    Задача генерации случайных чисел в достаточном количестве и за приемлемое время является большой проблемой. Надо заметить, что данный ресурс эту проблему до конца не решает.
                                      0
                                      Вот именно. Для генерации одного-двух чисел вполне сойдет и Random.nextInt(), а для большого количества запрос каждого числа с сервера просто обрекает программу на пониженную скорость + лимит трафика добивает.
                                        0
                                        Поэтому можно послать запрос на генерацию сразу огромного количества чисел. Это один запрос.
                                          0
                                          Это один http запрос, но числа все равно будут генерироваться по одному т.е. это просто удобство API, а не решение проблемы.
                                    0
                                    Грех-то оно, конечно грех, но, тем не менее, простому смертному вполне хватит хорошего генератора псевдослучайных чисел, например, Yarrow. Используется, например, в FreeBSD и AIX для /dev/random.
                                      +5
                                      Однажды я принимал участие в проекте, который представлял собой лотерею, для сертификации проекта в UK необходим был аудит кода + хардварный генератор случайных чисел, чтобы лотерея выдавала действительно рандомные значение, и ее результаты не могли быть подобраны или вычислены.
                                      Например для такого проекта был бы очень полезен такой сервис, тем более что частые запросы не требуются, гораздо важнее надежность рандомного генератора.
                                        0
                                        … Это должен был быть комментарий в корень обсуждения
                                          0
                                          Дык а эту самую сертификацию он бы прошел?
                                            0
                                            Тут я не рискну дать вам определенный ответ. Но если у random.org была бы нужная бумажка, то скорее всего да.
                                            +2
                                            Вообще говоря, /dev/random не такой уж и псевдослучайный в старом добром Linux
                                              +1
                                              Зато он невероятно медленный.

                                              Я как-то писал наивный конфигуратор, которому для идентификации нужно было сколько-то случайных чисел. На ~100-150 случайном символе начинались проблемы со скоростью.
                                                –1
                                                Неужели юзать API удаленного сайта быстрее? О_О
                                                  +1
                                                  При объёме данных — да. Если мне нужно 8 бит — быстрее у себя прочитать. Если нужно много — быстрее перетерпеть latency сети и получить нужное количество.
                                          +3
                                          Пользовался этим сервисом для лотереи по предметам из онлайн-игрушки. Псевдо-рандом заказчика не устроил, поэтому пришлось искать варианты использования true random. Из минусов могу отметить разве что ограничение для бесплатного пользования в 200 тысяч байт вроде. Сейчас уже отказались от данного сервиса и используем свою купленную железку www.idquantique.com/true-random-number-generator/quantis-usb-pcie-pci.html
                                            0
                                            А простенький самопальный радиоприемник, детектирующий помехи + звуковая карта не устраивали?
                                              0
                                              Не-а. Была идея со звуковой картой, но заказчик сам всё решил и купил железку.
                                                0
                                                Понятно. В коммерции, в принципе, проще купить. Это мы от недостатка денег вынуждены придумывать всякие наколенные поделки…
                                                  +1
                                                  Все просто — наколенная поделка может оказаться дороже в поддержке и рисках, чем готовая купленная.
                                              0
                                              200 тысяч бит, конечно.
                                              +2
                                              Как развлечение — сойдёт.
                                              Однако в серьёзных задачах глупо на него положиться.
                                              Если в случае псевдо-рандома «у себя» надо хотя бы сделать некоторые телодвижения, чтобы предсказать вывод, тут же злоумышленнику достаточно подменить по пути ответ сервера и радоваться жизни.
                                                +1
                                                1 Зачем подменить, если можно просниффать
                                                2 если введут https, то возможно от этого защититься
                                                3 без интернета это не работает
                                                4 Мне кажется, что лучше использовать генератор из TPM, который микросхема в компьютере, чем обращаться к этому сервису. Хотя в TPM могут быть закладки. Ну тогда с физического источника через какую-нибудь плату ардуино по юсб.
                                                И дешевле, и быстрее
                                                +1
                                                А что, если в один и тот же момент к сервису обратятся сразу два клиента?
                                                Первый — тот, кто собирается на основе данных сервиса хочет сгенерировать ключевую пару, а второй, естественно, злоумышленник.

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

                                                Логично, что для избежания этого нужно в конкретный момент времени выдавать значение ГСЧ только одному клиенту, но это моментально снижает производительность сервиса.
                                                  –4
                                                  Они умножают шум ветра на php rand() :D
                                                    0
                                                    >> в конкретный момент времени выдавать значение ГСЧ только одному клиенту, но это моментально снижает производительность сервиса.

                                                    Именно поэтому на сервисе есть ограничение на генерацию случайных чисел в день (на данный момент это 1 000 000 бит/день). Лимит можно увеличить за доплату.
                                                    +3
                                                    Клевый ресурс, заполняю лотерейные билетики с помощью него и пока вроде в плюсе;)
                                                      +4
                                                      исходя из тервера вы должны быть в минусе, следовательно либо ресурс не клевый, либо с лотереей что то не то:)
                                                        0
                                                        вот именно что исходя из тервера он может выиграть хоть все свои ставки. Вопрос только в размере выборки и связанной с ней вероятностью такого исхода.
                                                      –1
                                                      По-моему, разумно добавить подкласс класса java.util.Random. Вам потребуется только переписать защищённый метод next. Ну, разумеется, seed будете игнорировать, да readObject/writeObject станут бесполезны. Зато ваш класс можно будет подсовывать тем, кто уже пользуется java.util.Random. Ну и появятся автоматом приятные фишки типа nextGaussian().
                                                        0
                                                        Да, идея. Тут будет задействован Integer Generator, но проблема в том что методы либы не гарантировано возвращают результат, так как во время генерации может произойти ошибка 503. Тут уже надо кетчить ошибку, чтоб использовать интерфейс java.util.Random,
                                                        0
                                                        Не катит для высоконагруженных проектов. Разве что у Вас есть embedded вариант без обращений к внешним серверам…
                                                          0
                                                          Можно сочетать с псевдослучайным алгоритмом: время от времени подменять его seed на число, полученное с сервера (это можно делать асинхронно, тормозить не будет). Если заменить цепочку истинно случайных чисел на набор коротких случайных цепочек псевдослучайных чисел то, возможно, это устроит пользователя. Хотя, конечно, зависит от приложения.
                                                            0
                                                            Выход всегда можно найти. Из любой ситуации. Даже если отсечь задержку, то остаются еще всякие security policy… Но это так, к слову.
                                                            0
                                                            Зависит от задачи. Например, там есть возможность за раз выкачать pregenerated числа и при запросе рендома, использовать эти результаты уже без обращения к серверу.
                                                            +2
                                                            Я знаю, что они сделают первого апреля.
                                                              0
                                                              Поделитесь
                                                                +6
                                                                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
                                                            +2
                                                            А я по старинке пользуюсь книгой: goo.gl/XrkfY
                                                            Правда несколько неудобно из-за отсутствия сортировки — трудно найти нужное случайное число.
                                                              0
                                                              Очень круто. И в ней прямо числа одни случайные?
                                                                0
                                                                Да, 600 страниц отборных случайных чисел =)

                                                                Круче только многотомник с числом Пи, которого я не нашел в продаже, к сожалению.
                                                                  0
                                                                  Это прекрасно. Только мне пришло в голову, что, как только книжка написана, эти числа перестают быть случайными :). Даже если они такие крутые, что каждая книжка генерится отдельно. Тут неплохо было бы, конечно, определить тогда, что такое случайный.

                                                                  Просто первое, что мне пришло в голову насчет случайных чисел — это что невозможно построить некоторое правило, по которому начиная с некоторого N мы сможем предсказывать появление новых. Типа получается, что шумы мира не детерминированы, ну там, правило Гейзенберга, квантовые штуки, и поэтому тут то случайность настоящая. Если принять мое определение, книжка все портит.

                                                                  Хотя все равно это очень круто :)
                                                                    0
                                                                    Боюсь это пока несколько философский вопрос и здесь столько же искусства сколько математики, поэтому я всецело полагаюсь на авторритет авторов — RAND Corporation (http://www.rand.org/about.html).
                                                                0
                                                                Пардон, а как ей пользоваться?
                                                                  0
                                                                  Консенсуса в этом вопросе пока нет. Кто-то просто открывает и берет любое число по вкусу, кто-то по порядку, более серьезные специалисты ищут конкретное необходимое число, хотя это и занимает некоторое времени ввиду неотсортированности чисел.
                                                                    0
                                                                    Но ведь 80 баксов. За что?
                                                                      +1
                                                                      Абсолютно согласен — продешевили. Вот к примеру гораздо менее объемная работа стоит $495: goo.gl/UF0O5 при всем актуальности разбираемого вопроса.
                                                                +1
                                                                Да лучше заставить мышой поводить по экрану, ибо есть такие места (большинство), которые без инета ваще наглухо.
                                                                  0
                                                                  Сколько всего только не придумают люди, чтобы шафл в их MP3-плеере был хорошим…
                                                                    0
                                                                    Это, конечно, классно, что теперь есть еще одна возможность генерации абсолютно случайных чисел! Но вот только интересно, где может понадобиться абсолютная случайность в процессе разработке софта? Не кажется ли, что и псевдослучайные генераторы вполне справляются со своими задачами по генерации чисел? Я имею ввиду, что для обычного человека( пусть даже и программиста ) нет разницы между псевдослучайностью и абсолютной случайностью.

                                                                    P.S Кроме того, никто ведь точно не знает, может атмосферные шумы также, как и все в этом мире, цикличны… и предсказать число все же представляется возможным.

                                                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                    Самое читаемое