amobbs.com 阿莫电子技术论坛

标题: [LIB][C99]一个简单的伪随机数发生算法 [打印本页]

作者: Gorgon_Meducer    时间: 2010-4-16 18:17
标题: [LIB][C99]一个简单的伪随机数发生算法
本帖最后由 Gorgon_Meducer 于 2014-3-6 13:41 编辑


东西不复杂,我就不罗嗦了。当然,需要说明下,这个算法是我原创的。
如有雷同,纯属巧合。

此代码纯属交流目的,如用作安全领域,后果自负


#include <stdint.h>
#include <stdlib.h>


//! \brief random seed
static uint16_t s_hwRandomSeed = 0xAA55;
static uint8_t s_chRandomTable[] = {
                0x12,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF,
                0xF1,0xE2,0xD3,0xC4,0xB5,0xA6,0x97,0x88};


/*! \note set random generator seed
*  \param hwSeed random seed
*  \return none
*/
void set_random_seed( uint16_t hwSeed )
{
    s_hwRandomSeed ^= hwSeed;
}

/*! \note get a random integer
*  \param none
*  \return random integer value
*/
uint16_t get_random_u16( void )
{
    uint16_t *phwResult = (uint16_t *)&s_chRandomTable[(s_hwRandomSeed & 0x0E)];
   
    *phwResult += s_hwRandomSeed;
    s_hwRandomSeed ^= *phwResult;
   
    return *phwResult;
}

/*! \note get a random byte
*  \param none
*  \return random integer value
*/
uint8_t get_random_u8( void )
{
    return get_random_u16();
}
作者: dianzidog    时间: 2010-4-16 18:21
单片机搞随机数比较简单,对悬空AD脚采样就行了
作者: Gorgon_Meducer    时间: 2010-4-16 18:32
to 【1楼】 dianzidog
    是一个方法,不过系统时间太长……而且万一引脚没有悬空呢……万一还有其他AD应用呢?
你的PCB上会悬空引脚么?如果是一个低功耗应用呢?不允许悬空引脚……
作者: cgbabc    时间: 2010-4-16 19:30
学习
作者: cortex-m0    时间: 2010-4-16 19:47
不知随机数应用在哪?
作者: dianzidog    时间: 2010-4-16 19:54
回复【2楼】Gorgon Meducer  傻孩子
to&#160;【1楼】&#160;dianzidog
&#160;&#160;&#160;&#160;是一个方法,不过系统时间太长……而且万一引脚没有悬空呢……万一还有其他AD应用呢?
你的PCB上会悬空引脚么?如果是一个低功耗应用呢?不允许悬空引脚……
-----------------------------------------------------------------------

AVR某些引脚是只能用在ad上,不能做io的。而且这个是物理上的随机。
作者: dianzidog    时间: 2010-4-16 19:56
当然,用算法实现随机序列,时间比较短,但统计上的分布不是那么随机
作者: Gorgon_Meducer    时间: 2010-4-16 20:30
to 【6楼】 dianzidog
    并不是所有AVR芯片都有这样的AD引脚,而且有的封装有有的没有,典型的就是
M8的DIP和M8的TQFP……
    这个算法最大的特点就是“伪”。
作者: qhshilin    时间: 2010-4-16 22:00
>>>>>>>>>>>>>>>>>
作者: snoopyzz    时间: 2010-4-16 22:15
最常用的随机算法,C语言标准库函数的结果和这个一致
这里是32位机用的,8位机自己加UL,改int为long

int seed;

void srand(int s)
{
    seed = s;
}

int rand()
{
    seed = seed * 22695477 + 1;
}
作者: avrpicarm    时间: 2010-4-16 22:56
支持原创,
作者: mcu_lover    时间: 2010-4-16 22:59
傻大侠帖子,死了也要顶
作者: yangyi    时间: 2010-4-17 00:30
支持原创,感谢分享!
作者: zhenke    时间: 2010-4-17 01:05
谢谢!Mark!
作者: hongyancl    时间: 2010-4-17 09:23
dddd
作者: eduhf_123    时间: 2010-4-18 17:16
MARK 随机数
作者: ggyyll8683    时间: 2010-4-18 18:14
学习,感谢傻孩子分享!
作者: sunzhaod    时间: 2010-4-18 20:19
mark
作者: myhonour    时间: 2010-4-18 22:22
mark
作者: ilawp    时间: 2010-4-18 23:29
mark
作者: mcucow    时间: 2010-4-19 00:24
回复【1楼】dianzidog
单片机搞随机数比较简单,对悬空AD脚采样就行了
-----------------------------------------------------------------------

以前也用过, 不过真有个万一的情况, 看看这个算法, 顶起
作者: psocfans    时间: 2010-5-11 17:36
mark
作者: bad_fpga    时间: 2010-5-11 17:53
MARK
作者: wanglituan    时间: 2010-5-11 18:24
顶起
作者: david168    时间: 2010-5-13 11:41
精华 标记一下
作者: dengting    时间: 2010-7-4 02:46
自己先造一个大滚轮,这种方法常用于加密。
但随机数的话,出现雷同循环的数量取决滚轮的大小。
作者: dengting    时间: 2010-7-4 02:48
回复【20楼】mcucow
回复【1楼】dianzidog  
单片机搞随机数比较简单,对悬空ad脚采样就行了
-----------------------------------------------------------------------
以前也用过, 不过真有个万一的情况, 看看这个算法, 顶起
-----------------------------------------------------------------------

AD用来产生随机,请教,AD外围电路怎么搭?
又是怎样使用的呢?例如我要16位的随机数,怎样产生?我要32位的随机数,又怎样产生?随机出现的范围是不是0x0000000到0xffffffff呢?
太多的疑问。。。
作者: Spunky    时间: 2010-7-4 13:10
这个算法是完全可以预测的,安全性太差!
AD脚浮空倒是个办法,浮空脚加二极管钳位,需要产生随机数的时候打开AD读取,也不影响低功耗。
另外一个就是随即读取晶振的计数寄存器,同样可以获得随即数,方法很多!
作者: Gorgon_Meducer    时间: 2010-7-5 09:59
to 【27楼】 Spunky  
    没有说这个算法要用于安全用途阿。而且,库函数提供的方法本身也是具有可预知性的。
不然怎么叫做伪随机数。不过说句实话,你实际测试过要连续取多少个数据才会出现重复么?
另外,浮空AD获得的只是一个范围较小的随机数,可以说,精度是不够的。不过,如果使用
AD的采样结果来作为随机数的种子,倒是一个很不错的解决方案。
作者: projectbox    时间: 2010-7-21 22:52
什么原理?没看明白
作者: Notting_Hill    时间: 2010-8-13 14:42
mark 不错 随机数
作者: moon0213    时间: 2010-8-13 14:50
MARK
作者: jasonli    时间: 2010-8-30 11:45
mark
作者: xjmlfm1    时间: 2010-8-30 12:59
mark
作者: gdmfq    时间: 2010-8-31 11:04

作者: liulwn    时间: 2010-8-31 11:43
mark
作者: watch1030    时间: 2010-11-3 11:40
mark
作者: wanyou132    时间: 2010-11-3 16:57
MARK 随机数
作者: ag_wang    时间: 2010-12-19 19:18
手下,随机数
作者: embeddev    时间: 2011-3-16 10:51
说说原理?
作者: chenlijian80    时间: 2011-5-21 16:50
我的做法是用中断做个定时器,定时器里面做个16位的计数器。计数器在0-66535之间循环技术,当需要随机数的时候随时提取计数器里面的值就可以了。。
作者: Gorgon_Meducer    时间: 2011-5-21 18:23
to 【40楼】 chenlijian80
    在某些场合下,你的随机数会有规律性……
作者: usr.cn    时间: 2011-5-21 19:58
看应用了,伪的随机也有存在的价值。
作者: stone2006    时间: 2012-12-28 15:10
mark
跳频
作者: modelfly    时间: 2012-12-30 22:44
我比较喜欢读定时器的值。
作者: jjj    时间: 2012-12-30 23:20
我也是用记数器
作者: jeoge    时间: 2013-1-7 17:11
本帖最后由 jeoge 于 2013-1-7 17:13 编辑

还不如在时间中断里放一个计数器,随时取来用,取的数当然也是随机的,并且计数范围也是可以控制的。
作者: 鼎邑    时间: 2013-3-17 00:23
没有用过,但是mark下。
作者: younge    时间: 2013-4-14 21:24
Gorgon_Meducer 发表于 2010-7-5 09:59
to 【27楼】 Spunky  
    没有说这个算法要用于安全用途阿。而且,库函数提供的方法本身也是具有可预知性 ...

设置一个指针变量,指向ram里面的某个单元,需要时候读那个单元的数据作为随机数种子。因为程序运行时,ram的值可能因为实际情况随机变化……
除了程序可靠性隐患,不知还有没其他隐患
作者: jiaokx    时间: 2013-4-19 12:33
新手路过,
作者: 司马朝阳    时间: 2013-5-7 19:29
没学过 但是看看  学学  
作者: seeyou2013    时间: 2013-5-15 14:22
路过,帮顶了
作者: wenjinzaime    时间: 2013-6-9 10:47
支持下,多多交流才会有新东西出来!
作者: mcuandmex    时间: 2013-12-10 20:46
好贴 不过没用过还是没有懂
AD 计数器 指针
都可以产生随机数
作者: 滴答滴答下雨啦    时间: 2013-12-19 22:06
学习了……
作者: dgdzas    时间: 2014-1-10 11:57
younge 发表于 2013-4-14 21:24
设置一个指针变量,指向ram里面的某个单元,需要时候读那个单元的数据作为随机数种子。因为程序运行时,r ...

利用用的最多的暂存器即可
作者: wazhiyi    时间: 2014-1-10 12:02
提供了一种不错的思路
作者: hygs    时间: 2014-2-25 16:55
谢谢分享
作者: bondxie3    时间: 2014-3-6 12:55
傻孩子出品必是精品!
作者: dongfo    时间: 2014-4-17 09:47
简单实用,9错
作者: Micheal_J    时间: 2014-4-20 10:42
谢谢分享,正努力学习中
作者: YANGTUTAI    时间: 2014-4-22 00:19
buchuo ths..
作者: ray1136    时间: 2014-6-25 11:21
                            mark
作者: xiaoyonggo    时间: 2014-6-26 15:19
mark一下。
作者: gwuyu    时间: 2014-10-29 21:54
学习了,mark一下。

作者: jingmeidz    时间: 2014-10-30 23:38
收藏先,会用上的
作者: Ray______    时间: 2014-11-30 21:06
原来可以用AD口采随机数~~~受教
作者: liudijiang    时间: 2014-12-3 11:51
顶顶顶!!!!!!!!
作者: xiong57785    时间: 2014-12-31 13:43
mark  随机数   
作者: vivi_cq1982    时间: 2015-1-13 17:46
mark......
作者: retome    时间: 2015-11-14 09:00
不错 学习了·
作者: eryueniao    时间: 2015-12-25 10:17
本帖最后由 eryueniao 于 2015-12-25 10:44 编辑

haha学习啦,我用RTC做种子    。

   
   为什么是返回 return *phwResult;   这个值,而不是    s_hwRandomSeed                     
作者: ccitlad    时间: 2015-12-25 17:00
随机数 学习了!
作者: yanzhiwei    时间: 2015-12-26 15:29
支持原创  
作者: ldx24511    时间: 2016-4-22 16:19
我是通过AD+高速计数器+上电次数做为种子计算的
作者: yangbo18416    时间: 2016-10-24 16:22
收藏,最近准备弄跳频这一块
作者: vsdcjs    时间: 2017-3-15 10:05
很不错的
作者: amiok    时间: 2017-11-11 20:23
make~~~~~标记。
作者: Ray______    时间: 2017-11-11 22:06
用单次或者周期数次获取真的随机数做种子,配合伪随机发生器能到达真随机的效果吗。
作者: Gorgon_Meducer    时间: 2017-11-11 23:27
本帖最后由 Gorgon_Meducer 于 2017-11-11 23:28 编辑
Ray______ 发表于 2017-11-11 22:06
用单次或者周期数次获取真的随机数做种子,配合伪随机发生器能到达真随机的效果吗。 ...


“伪”随机数发生器发生出来的,本身就是伪随机的。做种子只不过是把取数的空间扩大而已
不可能是随机的。但是,如果用2到3个甚至更多不同规则的伪随机发生器以顺序的方式依次
产生随机数,这个就产生了混沌(Chaotic),那么就具有随机性了。

关键点就是,要打破函数的线性关系(一一对应),同时增加推演的级数。打破一一对应关系
其实很简单,远的不说,算CheckSum就是打破了一一对应关系——因为是把一堆数的单向
散列算出来了。然后用伪随机来打破线性关系,并增加多级这样的推演过程,就是破坏了还原
主义(Reductionism)成立的基本条件了。
作者: darkness27    时间: 2017-11-12 00:18
感谢分享,可不可以介绍一下原理思路呢?
很喜欢您的分享。
作者: 1826772880    时间: 2017-11-18 12:42
eryueniao 发表于 2015-12-25 10:17
haha学习啦,我用RTC做种子    。

   

粗略看了下,s_hwRandomSeed这个值是作为下次运算用的吧,正所谓不固定




欢迎光临 amobbs.com 阿莫电子技术论坛 (https://www.amobbs.com/) Powered by Discuz! X3.4