Quais algoritmos comuns são usados ​​para o rand () do C?

Eu entendo que a especificação C não fornece nenhuma especificação sobre a implementação específica de rand() . Quais algoritmos diferentes são comumente usados ​​em diferentes plataformas principais? Como eles diferem?

    Veja este artigo: http://en.wikipedia.org/wiki/List_of_random_number_generators

    Este é o código-fonte do rand() da glibc:

     /* Reentrant random function from POSIX.1c. Copyright (C) 1996, 1999, 2009 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1996. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include  /* This algorithm is mentioned in the ISO C standard, here extended for 32 bits. */ int rand_r (unsigned int *seed) { unsigned int next = *seed; int result; next *= 1103515245; next += 12345; result = (unsigned int) (next / 65536) % 2048; next *= 1103515245; next += 12345; result < <= 10; result ^= (unsigned int) (next / 65536) % 1024; next *= 1103515245; next += 12345; result <<= 10; result ^= (unsigned int) (next / 65536) % 1024; *seed = next; return result; } 

    Fonte: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib/rand_r.c;hb=HEAD

    Como você pode ver, é simplesmente multiplicar por uma adição e uma mudança. Os valores são cuidadosamente escolhidos para garantir que você não receba nenhuma repetição da saída para as iterações RAND_MAX.

    Observe que esta é uma implementação antiga que foi substituída por um algoritmo mais complexo: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib/random_r.c;hb=HEAD

    Se o link se quebrado, o Google para "glibc rand_r"

    Certa vez, escrevi um relatório sobre CRNGs para um curso de Matemática Discreta. Para isso, desmontei o rand () em msvcrt.dll:

     msvcrt.dll:77C271D8 mov ecx, [eax+14h] msvcrt.dll:77C271DB imul ecx, 343FDh msvcrt.dll:77C271E1 add ecx, 269EC3h msvcrt.dll:77C271E7 mov [eax+14h], ecx msvcrt.dll:77C271EA mov eax, ecx msvcrt.dll:77C271EC shr eax, 10h msvcrt.dll:77C271EF and eax, 7FFFh 

    Então é um LCG algo como (não testado) …

     int ms_rand(int& seed) { seed = seed*0x343fd+0x269EC3; // a=214013, b=2531011 return (seed >> 0x10) & 0x7FFF; } 

    O campo de PRNGs (Pseudo Random Number Generators) é bastante vasto.

    Primeiro de tudo você tem que entender que sem ter uma input externa (geralmente física) você não pode obter uma fonte real de números randoms. É por isso que esses algoritmos são chamados pseudo randoms : eles geralmente usam uma semente para inicializar uma posição em um sequência muito longa que parece aleatória, mas não é aleatória.

    Um dos algoritmos mais simples é o Linear Congruential Generator ( LCG ), que tem algumas restrições para garantir uma sequência longa e não é nada seguro.

    Outro engraçado (pelo menos para o nome) é o Blum Blum Shub Generator ( BBS ) que é incomum para PRNGs normais porque depende da exponenciação em módulo aritmético dando uma segurança comparável a outros algoritmos como RSA e El Gamal em quebrar a sequência ( também se não tenho certeza sobre a prova disso)

    Você pode usar a biblioteca Boost Random para geradores de números randoms diferentes, se precisar de algo específico ou mais avançado.

    A documentação do Boost Random está aqui .