【问题标题】:C custom random functionC自定义随机函数
【发布时间】:2011-06-20 20:31:09
【问题描述】:

我想用 C 语言创建一个快速的轻量级函数,它返回一个伪随机无符号字符。对我(ANSI C 程序员)来说,具有挑战性的部分是我不能使用<stdio.h> 或任何其他现成的函数。有什么建议吗?

我所说的“快速”是指:避免不必要的代码(例如 if 语句、循环等) 我所说的“轻量级”是指:尽可能少地使用变量

谢谢

【问题讨论】:

  • 定义“快速”、“轻量级”和“随机”...尤其是“随机”。
  • “具有挑战性的部分”是“家庭作业的要求”的同义词吗?
  • int rand() { return 5;}
  • @GregS:我敢肯定,是由公平骰子选择的。
  • 同意 Nemo,您的要求对于一个好的答案来说有点太模糊了。我有一个肯定满足“快速”的答案,但如果不了解您的应用程序,我无法判断“轻量级”或“随机”。

标签: c random srand


【解决方案1】:

Use a Linear Congruential Generator

例如

uint32_t state = 777;

char myRand()
{
   state = state * 1664525 + 1013904223;
   return state >> 24;
}

注意myRand 返回高位,它们比低位更伪随机。

线性同余发生器由 D. H. Lehmer 在 1949 年引入(参见 Proc. 2nd Symp. on Large-Scale Digital Calculating Machinery (Cambridge, MA: Harvard University Press, 1951), 141-146)。我给出的具体数字常数似乎来自 Press, William H.;等。 (1992)。 Fortran 77 中的数值食谱:科学计算的艺术(第 2 版)。国际标准书号 978-0-521-43064-7。

【讨论】:

  • -1:LCG 并不是随机的,不建议用于新应用。
  • 我理解 OP 他想要一个尽可能简单的解决方案。无论如何,没有确定性生成器是随机的。
  • 如果 OP 的要求排除了比 LCRNG 更好的东西,那么他们就错了。
  • 也许他想生成简单的低级 8 位音频噪声,我该认识谁? LCG 是一个合理的选择。
  • 公平地说,这段代码是由 Knuth 提供的,如在 C 语言中的数字食谱,第二版,第 284 页中所见。
【解决方案2】:

来自linux内核源代码(random32.c)

rnd_state 中的值应初始化为:s1 > 1, s2 > 7, s3 > 15。

论文声称这是一个最大等分布的组合 Tausworthe 生成器 基于来自 GNU Scientific Library 1.5(2004 年 6 月 30 日)的代码

struct rnd_state {
    u32 s1, s2, s3;
};

static u32 __random32(struct rnd_state *state)
{
#define TAUSWORTHE(s,a,b,c,d) ((s&c)<<d) ^ (((s <<a) ^ s)>>b)

    state->s1 = TAUSWORTHE(state->s1, 13, 19, 4294967294UL, 12);
    state->s2 = TAUSWORTHE(state->s2, 2, 25, 4294967288UL, 4);
    state->s3 = TAUSWORTHE(state->s3, 3, 11, 4294967280UL, 17);

    return (state->s1 ^ state->s2 ^ state->s3);
}

学术界:http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps

【讨论】:

【解决方案3】:

发明你自己的随机数生成器与发明你自己的密码学是同一类的一个坏主意:很容易构造一些看似的东西来完成这项工作,但实际上效率极低;构建真正可以完成工作的东西要困难得多。阅读RANDU 的警示故事,然后下载Mersenne Twister 的变体之一并使用它。

【讨论】:

  • 2.5KB 的内部状态在任何现代环境中都是轻量级的,但对于最深入的嵌入,MT 人员现在还提供 TinyMT,它只需要 127 位的内部状态,仍然比任何环境都好LCRNG。
  • 这是 OP 想要一些他们不应该得到的东西的时代之一。如果 OP 就他们的 RC4 实施征求意见,你会给他们吗?
  • 你怎么知道他没有使用微控制器?
  • 在这种情况下,他仍然可以使用 TinyMT 或您建议的 Tausworthe 生成器。真的,我想在这里磨练的唯一轴是“没有人应该再使用 LCRNG”和“不要试图重新发明这个轮子”。
  • ok hexa 明白了这一点,我想我应该重新发明一个很久以前建造的轮子。我真的不知道 TINYMC,但我会查一下。谢谢
【解决方案4】:

在 Wikipedia 上有完整的伪随机数生成器列表:http://en.wikipedia.org/wiki/List_of_pseudorandom_number_generators

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-08
    • 1970-01-01
    • 2017-09-23
    • 1970-01-01
    • 2014-01-23
    • 2014-05-29
    • 2018-01-15
    • 2014-04-27
    相关资源
    最近更新 更多