В мире компьютеров часто нужны случайные данные. В тех же компьютерных играх, например для расчета шанса выпадения вкусной шмотки с поверженного врага. Вопрос получения действительно хороших случайных чисел выходит за рамки поста, поэтому тут о нем - ни слова. А о чем будет пост? О том, как в разных программных продуктах случайные числа получают, о том как понять какая именно функция работает внутри ПО. Желающие углубиться в потроха glibc/msvcrt/PHP и кучу цифр приглашаются под кат.
Грубо говоря, все ГСЧ имеют 2 функции: инициализация и получение случайного числа. Первые часто называют randomize(), srand() и т.п. Вторые - rand(), random(). Допустим, мы можем выполнить на исследуемой системе такой псевдокод:
srand(0);
for (int i = 0; i<4; i++){printf(random());}
То есть инициализация ГПСЧ нулем и вывод 4 последовательных результатов. По ним мы и будем определять что перед нами.
Delphi: - 0, 134775813 (0x8088405), 3698175006, 870078619 - старый добрый LCRNG из функции RandInt.
Visual C - 38, 7719, 21238, 2437 - тоже LCRNG из функций srand/rand.
Где-то здесь начинается ад и погибель, мы переходим к glibc
Glibc - широко используемая библиотека, имеет разные ГПСЧ в зависимости чуть ли не от погоды на марсе. Начнем с того, что в ней есть LCRNG и более сложный LSFR-like (имеет внутреннее имя Type3) генераторы. Более того, для LCRNG вывод будет разным в винде и в никсах!
12345, 5758, 10207, 7212 - винды, LCRNG
12345, 1406932606, 654583775, 1449466924 - никсы, все тот же LCRNG.
1804289383, 846930886, 1681692777, 1714636915 - Type3
BSD Lib - системная библиотека в FreeBSD и как говорят в Mac OS. Имеет функции srand/rand и srandom/random, которые ведут себя по разному. Вывод будет дан в 16-ричной системе:
0x1F0CCE42 0x1B95EFB 0x310AB19F 0x351356E0 - srand/rand - Вроде бы LCRNG, но со своими особенностями
0x226E5331 0x4A656E89 0xB80544B 0x88FAD1F - srandom/random - практически полный аналог Glibc Type 3, отличие в 1 строке. Но как меняет результаты!
PHP - к аду и погибели из предыдущих пунктов присоединяются толпы чертей и прочей нежити, чтобы никто не ушел живым! Сей славный язык имеет три функции: rand(), rand(min, max) и array_rand(), но нас будет интересовать только rand(). PHP использует внутри себя библиотеки, зачастую системные. На BSD-системе он будет использовать BSD Lib, в никсах - Glibc, а винде - тоже Glibc. Кроме того, на PHP могут накатываться патчи, например suhosin и тогда он начинает игнорировать srand().
В результате экспериментов было выяснено, что сборка xampp в винде использует Glibc LCRNG виндовый. PHP во FreeBSD - random() из BSD Lib, а PHP в линухе - Glibc Type3-генератор, последовательности для них выше. На все эти варианты могут опираться функции random(min, max) и array_rand(), вот такой вот зоопарк.
Еще PHP имеет функции mt_srand и mt_rand(), они используют Mersenne Twister и их вывод я вам не покажу! И с ними пока довольно много вопросов.
Остальное за кадром остались Cygwin, VB, Java, Python, Perl и туева хуча других библиотек и языков! Если вы хотите внести посильную лепту в мое погружение в это болото - выполните приведенный код дважды и если результаты одинаковые - пришлите их мне. Разные результаты будут говорить об игнорировании srand() и это пока большая проблема.
PS. Обновлено про BSD