我想生成0和某个整数之间的(伪)随机数。我不介意他们是不是太随机了。我可以访问当天的当前时间,但不能访问rand功能。任何人都可以想到一种足够强大的方法来生成这些吗?也许,从一天中的某个时间丢弃一些比特并取模数我的整数或其他东西?
我正在使用c。
如果您使用的是超简单的伪随机生成器,则可以使用Linear Feedback shift Register。
维基百科文章有一些代码片段供您查看,但基本上16位生成器的代码看起来像这样(从该页面轻轻按摩......)
unsigned short lfsr = 0xACE1u;
unsigned bit;
unsigned rand()
{
bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5) ) & 1;
return lfsr = (lfsr >> 1) | (bit << 15);
}
一个最简单的随机数生成器,它不会返回相同的值:
uint16_t simpleRand(void)
{
static uint16_t r = 5531; //dont realy care about start value
r+=941; //this value must be relative prime to 2^16, so we use all values
return r;
}
如果您不希望序列始终以相同的值启动,您可以获得设置起始值的时间。
对于“不太随机”的整数,您可以从当前的UNIX时间开始,然后使用递归公式r = ((r * 7621) + 1) % 32768;
。在第n次迭代之后,0
(包括)和M
(不包括)之间的第n个随机整数将是r % M
。
这称为线性同余生成器。
递归公式是bzip2用于在其快速排序实现中选择枢轴的内容。我不知道其他目的,但它对这个特别的一个很好...
看看你自己实现的伪随机生成器(rand()
里面是什么),例如Mersenne twister是备受推崇的。
唯一“强大”(不易预测)的方法是编写自己的伪随机数生成器并将其与当前时间一起播种。必须的维基百科链接:http://en.wikipedia.org/wiki/Pseudorandom_number_generator
你可以在这里找到“Tiny Mersenne Twister”:http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html
它纯粹,易于使用。例如。只是使用时间:
#include "tinymt32.h"
// And if you can't link:
#include "tinymt32.c"
#include <time.h>
#include <stdio.h>
int main(int argc, const char* argv[])
{
tinymt32_t state;
uint32_t seed = time(0);
tinymt32_init(&state, seed);
for (int i=0; i<10; i++)
printf("random number %d: %u\n", i, (unsigned int)tinymt32_generate_uint32(&state));
}
下面提供了使用范围的最小且简单的随机发生器以及完整的工作示例。
unsigned int MyRand(unsigned int start_range,unsigned int end_range)
{
static unsigned int rand = 0xACE1U; /* Any nonzero start state will work. */
/*check for valid range.*/
if(start_range == end_range) {
return start_range;
}
/*get the random in end-range.*/
rand += 0x3AD;
rand %= end_range;
/*get the random in start-range.*/
while(rand < start_range){
rand = rand + end_range - start_range;
}
return rand;
}
int main(void)
{
int i;
for (i = 0; i < 0xFF; i++)
{
printf("%u\t",MyRand(10,20));
}
return 0;
}
如果你没有太快地产生你的数字(* 1)并且你的上限足够低(* 2)并且你的“时间”包括纳秒,那么只需使用那些纳秒。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int nanorand(void) {
struct timespec p[1];
clock_gettime(CLOCK_MONOTONIC, p);
return p->tv_nsec % 1000;
}
int main(void) {
int r, x;
for (;;) {
r = nanorand();
do {
printf("please type %d (< 50 quits): ", r);
fflush(stdout);
if (scanf("%d", &x) != 1) exit(EXIT_FAILURE);
} while (x != r);
if (r < 50) break;
}
puts("");
return 0;
}
一个样本运行...
please type 769 (< 50 quits): 769 please type 185 (< 50 quits): 185 please type 44 (< 50 quits): 44
(* 1)如果您以交互方式使用它们,一次一个 (* 2)如果你想要数字大约1000
import java.io.*;
public class random{
public static class p{
}
static long reg=0;
static long lfsr()
{
if(reg==0)
{
reg=145896027340307l;
}
long bit=(reg>>0^reg>>2^reg>>3^reg>>5)&1;
reg=reg>>1|bit<<62;
return reg;
}
static long getRand()
{
String s=String.valueOf(new p());
//System.out.println(s);
long n=0;
lfsr();
for(int i=0;i<s.length();i++)
{
n=n<<8|+s.charAt(i);
}
System.out.print(n+" "+System.currentTimeMillis()+" "+reg+" ");
n=n^System.currentTimeMillis()^reg;
return n;
}
public static void main(String args[])throws IOException
{
for(int i=0;i<400;i++)
{
System.out.println(getRand());
}
}
}
这是一个随机数生成器,可以保证序列永远不会重复。我将对象值(由Java随机放置)与LFSR配对。
好处:
缺点:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
int main()
{
unsigned int x,r,i;
// no of random no you want to generate
scanf("%d",&x);
// put the range of random no
scanf("%d",&r);
unsigned int *a=(unsigned int*)malloc(sizeof(unsigned int)*x);
for(i=0;i<x;i++)
printf("%d ",(a[i]%r)+1);
free(a);
getch();
return 0;
}