首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C的rand()有哪些常用的算法?

C的rand()有哪些常用的算法?
EN

Stack Overflow用户
提问于 2009-06-22 09:47:11
回答 4查看 31.6K关注 0票数 27

我知道C规范没有给出任何关于rand()的具体实现的规范。在不同的主要平台上通常使用哪些不同的算法?它们有什么不同?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-06-22 10:00:25

请参阅本文:http://en.wikipedia.org/wiki/List_of_random_number_generators

这是glibc的rand()的源代码

代码语言:javascript
复制
/* 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 <drepper@cygnus.com>, 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 <stdlib.h>


/* 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;
}

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

如你所见,它只是简单的乘以一个加法和一个移位。这些值经过仔细选择,以确保不会重复RAND_MAX迭代的输出。

注意,这是一个旧的实现,已经被一个更复杂的算法所取代:https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib/random_r.c;hb=HEAD

如果链接断开,谷歌搜索"glibc rand_r“

票数 24
EN

Stack Overflow用户

发布于 2009-08-15 00:03:50

我曾经为离散数学的一门课程写过一篇关于CRNG的报告。为此,我在msvcrt.dll中反汇编了rand():

代码语言:javascript
复制
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

所以它是一个LCG类似于(未测试的)..。

代码语言:javascript
复制
int ms_rand(int& seed)
{
  seed = seed*0x343fd+0x269EC3;  // a=214013, b=2531011
  return (seed >> 0x10) & 0x7FFF;
}
票数 13
EN

Stack Overflow用户

发布于 2009-06-22 23:24:23

伪随机数发生器(PRNG)的领域是相当广阔的。

首先,您必须了解,如果没有外部输入(通常是物理输入),您就无法获得真正的随机数源。这就是为什么这些算法被称为伪随机:它们通常使用种子来初始化非常长的序列中的位置,这看起来是随机的,但它根本不是随机的。

最简单的算法之一是线性同余生成器 (LCG),它有一些约束来保证长序列,而且它根本不安全。

另一个有趣的(至少在名字上)是Blum Blum Shub Generator (BBS),这对于普通的PRNG来说是不寻常的,因为它依赖于模算术中的求幂,在打破序列方面提供了与RSA和El Gamal等其他算法相当的安全性(如果我也不确定它的证明)

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1026327

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档