分享一个简易的随机数算法,请大家指正
用单片机生成随机数算法,伪随机,使用姚老板的12c5a60s2芯片,详情见文档输入[0,65536)
输出[0,65536)
-
-
-
U16 rand65536( CU16 seed )/*2018.04.13Python+excel验证*/
{
code U8 table =
{
108,166,74,119,198,161,224,60,106,227,26,20,44,55,172,91,69,194,70,125,249,188,113,8,155,114,
205,37,63,47,57,217,177,71,244,65,52,61,132,123,196,242,43,73,12,187,247,151,184,81,90,255,
175,51,143,59,239,27,186,7,2,46,24,131,109,96,203,42,218,146,174,72,110,102,160,169,222,56,
207,13,180,250,116,67,171,84,100,9,137,6,129,141,154,240,122,202,219,163,130,216,75,135,221,98,
157,88,226,253,33,101,103,138,204,121,127,193,89,85,62,94,139,86,34,115,168,152,142,16,126,170,
120,15,76,10,147,29,183,4,148,40,66,32,87,105,124,214,162,140,234,235,68,104,220,92,167,212,
233,14,248,78,210,144,236,112,209,201,19,93,97,182,58,118,153,38,211,50,192,45,35,254,165,
0,229,237,25,208,1,23,17,158,21,95,195,164,223,243,48,199,181,145,53,228,83,190,117,5,
173,54,197,18,80,231,159,200,213,252,128,215,31,150,49,64,251,179,3,82,28,206,230,246,225,
11,36,149,136,245,22,232,30,238,185,191,176,241,77,39,156,41,99,189,134,79,133,178,111,107
};
auto xdata U16 t1, t2;
t1 = seed / 256;
t2 = seed % 256;
return( table[( t1 + t2 ) % 256 ] * 256 + table[ 255 - t2 ] );
} 附件上传 这个是随机数生成器?
如果输入seed 的值每次都一样,输出的不都是一样的吗? sunrn123 发表于 2018-4-13 16:44
这个是随机数生成器?
如果输入seed 的值每次都一样,输出的不都是一样的吗? ...
是的输入一样,输出一样,输入可以迭代嘛,比如递增或递减,达到输出不重复的伪随机数效果 这跟数组有啥区别? shange144k8 发表于 2018-4-13 16:47
是的输入一样,输出一样,输入可以迭代嘛,比如递增或递减,达到输出不重复的伪随机数效果 ...
哈哈,输入一样输出一样还能叫随机吗,如果这样都能接受的话你写这函数干啥,直接用种子做索引查表就行了嘛,绕了个大弯多此一举 jcrorxp 发表于 2018-4-13 16:49
这跟数组有啥区别?
区别不大,相当于用256个元素实现65536个元素,当然如果再扣一层迭代可以实现更多的元素 {:sweat:}{:sweat:}{:sweat:}{:sweat:}{:sweat:}{:sweat:} jiaowoxiaolu 发表于 2018-4-13 16:50
哈哈,输入一样输出一样还能叫随机吗,如果这样都能接受的话你写这函数干啥,直接用种子做索引查表就行了 ...
嗯一开始我也想做数组索引,但要实现索引6万个元素,1是要代码空间,而是编辑这个6万字的文本太费劲 本帖最后由 lsfsxfljj 于 2018-4-13 16:58 编辑
真麻烦,弄个计数器让他跑,要数据的时候去取一下,随机了吧{:lol:}{:lol:}{:lol:}{:lol:} lsfsxfljj 发表于 2018-4-13 16:56
真麻烦,弄个计算器让他跑,要数据的时候去取一下,随机了吧 ...
随机不重复,理论山真随机有重复的可能,这个随机不会重复 shange144k8 发表于 2018-4-13 16:58
随机不重复,理论山真随机有重复的可能,这个随机不会重复
随机也是在有限的集合内取出一个而已,你都定死了随什么机啊,弄个计数器最好了 lsfsxfljj 发表于 2018-4-13 17:00
随机也是在有限的集合内取出一个而已,你都定死了随什么机啊,弄个计数器最好了 ...
嗯,说的也是,又学到一个方法,{:handshake:} shange144k8 发表于 2018-4-13 17:02
嗯,说的也是,又学到一个方法,
是啊如果你这个数组是ADC引脚上的波动,那就差不多真是随机了. jcrorxp 发表于 2018-4-13 17:07
是啊如果你这个数组是ADC引脚上的波动,那就差不多真是随机了.
是的,adc波动是个常规方法 jcrorxp 发表于 2018-4-13 17:07
是啊如果你这个数组是ADC引脚上的波动,那就差不多真是随机了.
问题是好的adc能做到dc下95%恒定率,其余5%也就+-1。。。 ADC读 最低位每次只要最低位采集 8次就是一个 uint8 的随机数
利用stm32 内部 adc 产生随机数
//随机数初始化
void init_randSeed(unsigned int *seeds,int len)
{
__IOunsigned int seed=0;
int i;
for(i=0; i<len; i++)
{
seed|=(seeds&0x01);
seed<<=1;
}
srand(seed);
}
void init_adc()
{
__IO float Temper;
unsigned int uhADCxConvertedValue;
int i;
for(i=0; i<32; i++)
{
if(HAL_ADC_Start(&hadc1) == HAL_OK)
{
HAL_ADC_PollForConversion(&hadc1, 30);
uhADCxConvertedValue = HAL_ADC_GetValue(&hadc1);
}
//温度
Temper = (uhADCxConvertedValue*3300/4096-760)/2.5 + 25;
}
init_randSeed(uhADCxConvertedValue,32);
} 1、伪随机一般实在没办法取得随机种子的前提下才使用的。
2、随机种子一般可以从按键触发时间,ad随机采样,两个独立时钟差值产生。
比如可以用两个时钟源,最好是悬殊较大的时钟源,各自计数,随机数就直接从差值里面取,范围直接就是低几位 gongxd 发表于 2018-4-13 22:04
利用stm32 内部 adc 产生随机数
恩,很好的方法 shower.xu 发表于 2018-4-13 22:32
1、伪随机一般实在没办法取得随机种子的前提下才使用的。
2、随机种子一般可以从按键触发时间,ad随机采样 ...
如果都有随机种子了那就不需要随机数了,随机种子本生就是随机数,所以我对种子的理解就是种子连续 楼主在论坛里多检索一下,有很多实施的方案可以用,直接拿来就行了
C语言标准库自带的随机函数,在单片机上用的话,生成的数据不保证是唯一的,因为随机种子不一定唯一,如果保证随机种子唯一,生成随机数的方法rand()
可以直接用,那么现在随机种子的方法有以下两种
1.基于时间戳的随机
2.基于AD采样值的随机
这个叫随机数?还不如用标准库的那个 18楼的方法好用 计数器是个好办法 不知道什么情况要用随机数,什么 产品 用AD方法产生随机数还是比较常见的 磊磊映画 发表于 2018-4-14 07:49
楼主在论坛里多检索一下,有很多实施的方案可以用,直接拿来就行了
C语言标准库自带的随机函数,在单片机 ...
rand()函数产生的数貌似随机,但是如果种子相近随机也相近,时间戳和ad是真随机,但如果我要取6万个数,怎么能保证他们不重复呢 zuu0 发表于 2018-4-14 10:20
不知道什么情况要用随机数,什么 产品
等效于在屏幕上打印随机点,铺满某一个区域,且打点不重复,点的数量在6万个左右 弄一个256的表,弄一个计数器放在MAIN里计,要的时候取一下,在表里查一下,如果有相同的值就丢,再计一下 不相同就放表里,拿去用,完成了256个,把表清掉,,重头再来,这样是不是可以实现256个随机且不同的数了? avrydy 发表于 2018-4-14 18:43
不相同就放表里,拿去用,完成了256个,把表清掉,,重头再来,这样是不是可以实现256个随机且不同的数了? ...
是啊基本就是这个道理,我的方法是用256个随机数实现65535个,使用了循环迭代保证了每次取出组合成不同的数值,就不用去比较了,要是逐个比较那运算量太大了,就这样跑65536个数都要0.67秒@22.1184mhz shange144k8 发表于 2018-4-14 15:50
rand()函数产生的数貌似随机,但是如果种子相近随机也相近,时间戳和ad是真随机,但如果我要取6万个数 ...
时间戳肯定不会重复啊,时间戳是从1970年至今的秒计时数,最大范围至2的32次 幂,6W个不算什么 磊磊映画 发表于 2018-4-16 09:02
时间戳肯定不会重复啊,时间戳是从1970年至今的秒计时数,最大范围至2的32次 幂,6W个不算什么 ...
是啊,就是数太大,如果要把这个大数拿来去对应一个0~到6万以内的数,就有重复的可能 磊磊映画 发表于 2018-4-16 09:02
时间戳肯定不会重复啊,时间戳是从1970年至今的秒计时数,最大范围至2的32次 幂,6W个不算什么 ...
能贴具体代码来学习下么{:handshake:} shange144k8 发表于 2018-4-16 09:36
能贴具体代码来学习下么
u16 Adapter_GetRandSN(void)
{
static u16 rand_SN=0;
if(rand_SN==0) {
srand(g_VendoutSerialNumberSeed);/*载入随机种子*/
rand_SN = rand();
if(rand_SN ==0) rand_SN = 100;
}
return rand_SN++;
}
/**********************************
//名称: SysTick_Handler
//功能: 系统滴答中断函数
//入口参数: 无
//出口参数: 无
**********************************/
void SysTick_Handler(void)
{
g_VendoutSerialNumberSeed++; //出货流水号随机种子数
}
ADC是个好办法 shange144k8 发表于 2018-4-14 15:50
rand()函数产生的数貌似随机,但是如果种子相近随机也相近,时间戳和ad是真随机,但如果我要取6万个数 ...
随机和重复不是一个概念 本帖最后由 apple_eat 于 2018-4-16 19:33 编辑
标准库rand()函数的缺陷以及Blitz++随机数生成的简介
https://yq.aliyun.com/articles/226618
另外,有时候需要随机,但是概率可控,游戏中的暴率等等,涉及到问题就更复杂了. N年前用80C31+RC振荡器+T1记脉冲个数做随机值。当时有内置的ADC就方便了。 lhj200304 发表于 2018-4-16 19:25
随机和重复不是一个概念
是的,不是一个概念 apple_eat 发表于 2018-4-16 19:31
标准库rand()函数的缺陷以及Blitz++随机数生成的简介
https://yq.aliyun.com/articles/226618
感谢,你提供的资料很有参考价值{:handshake:} mon51 发表于 2018-4-16 21:21
N年前用80C31+RC振荡器+T1记脉冲个数做随机值。当时有内置的ADC就方便了。
能简单描述一下用在什么产品中么 单片机生成随机数一直是一个比较麻烦的问题。 用AD生成随机数还真是好办法
ndust 发表于 2018-4-17 10:41
单片机生成随机数一直是一个比较麻烦的问题。
是的,走了不少弯路
页:
[1]