C语言生成32位和64位随机数算法
C语言生成32位和64位随机数算法
/** * randstd.h * * Standard definitions and types, Bob Jenkins * * 2015-01-19: revised by cheungmine */ #ifndef _RANDSTD_H__ #define _RANDSTD_H__ #ifndef STDIO # include <stdio.h> # define STDIO #endif #ifndef STDDEF # include <stddef.h> # define STDDEF #endif typedef unsigned long long ub8; #define UB8MAXVAL 0xffffffffffffffffLL #define UB8BITS 64 typedef signed long long sb8; #define SB8MAXVAL 0x7fffffffffffffffLL typedef unsigned long int ub4; /* unsigned 4-byte quantities */ #define UB4MAXVAL 0xffffffff typedef signed long int sb4; #define UB4BITS 32 #define SB4MAXVAL 0x7fffffff typedef unsigned short int ub2; #define UB2MAXVAL 0xffff #define UB2BITS 16 typedef signed short int sb2; #define SB2MAXVAL 0x7fff /* unsigned 1-byte quantities */ typedef unsigned char ub1; #define UB1MAXVAL 0xff #define UB1BITS 8 /* signed 1-byte quantities */ typedef signed char sb1; #define SB1MAXVAL 0x7f /* fastest type available */ typedef int word; #define bis(target,mask) ((target) |= (mask)) #define bic(target,mask) ((target) &= ~(mask)) #define bit(target,mask) ((target) & (mask)) #ifndef min # define min(a,b) (((a)<(b)) ? (a) : (b)) #endif /* min */ #ifndef max # define max(a,b) (((a)<(b)) ? (b) : (a)) #endif /* max */ #ifndef abs # define abs(a) (((a)>0) ? (a) : -(a)) #endif #ifndef align # define align(a) (((ub4)a+(sizeof(void *)-1))&(~(sizeof(void *)-1))) #endif /* align */ #define RAND_TRUE 1 #define RAND_FALSE 0 #define RAND_SUCCESS 0 /* 1 on VAX */ #endif /* _RANDSTD_H__ */
/** * rand.h * definitions for a random number generator * ----------------------------------------------------------------------------- * By Bob Jenkins, 1996, Public Domain * MODIFIED: * 960327: Creation (addition of randinit, really) * 970719: use context, not global variables, for internal state * 980324: renamed seed to flag * 980605: recommend RANDSIZL=4 for noncryptography. * 010626: note this is public domain * ----------------------------------------------------------------------------- * * 2015-01-19: revised by cheungmine */ #ifndef _RAND_H__ #define _RAND_H__ #ifdef __cplusplus extern "C" { #endif #include "randstd.h" #define RANDSIZL (8) #define RANDSIZ (1<<RANDSIZL) /** * context of random number generator */ struct randctx_ub4 { ub4 randcnt; ub4 seed[RANDSIZ]; ub4 mm[RANDSIZ]; ub4 aa; ub4 bb; ub4 cc; }; typedef struct randctx_ub4 randctx; /** * context of random number generator for 64-bits int */ struct randctx_ub8 { ub8 randcnt; ub8 seed[RANDSIZ]; ub8 mm[RANDSIZ]; ub8 aa; ub8 bb; ub8 cc; }; typedef struct randctx_ub8 randctx64; /** * randinit * init rand seed */ extern void rand_init(randctx *r, word time_as_seed); extern void rand64_init(randctx64 *r, word time_as_seed); /** * rand * Call rand(randctx *) to retrieve a single 32-bit random value. */ extern ub4 rand(randctx *r); extern ub4 randint(randctx *r, ub4 rmin, ub4 rmax); extern ub8 rand64(randctx64 *r); extern ub8 randint64(randctx64 *r, ub8 rmin, ub8 rmax); #ifdef __cplusplus } #endif #endif /* _RAND_H__ */
/** * rand.c * By Bob Jenkins. My random number generator, ISAAC. Public Domain. * ----------------------------------------------------------------------------- * MODIFIED: * 960327: Creation (addition of randinit, really) * 970719: use context, not global variables, for internal state * 980324: added main (ifdef'ed out), also rearranged randinit() * 010626: Note that this is public domain * ----------------------------------------------------------------------------- * * 2015-01-19: revised by cheungmine */ #include "rand.h" #include <time.h> /** *============================================================================== * 32-bits int random generator *============================================================================== */ #define isaac_golden_ratio32 0x9e3779b9 #define ind32(mm,x) (*(ub4 *)((ub1 *)(mm) + ((x) & ((RANDSIZ-1)<<2)))) #define rngstep32(mix,a,b,mm,m,m2,r,x) \ { \ x = *m; \ a = (a^(mix)) + *(m2++); \ *(m++) = y = ind32(mm,x) + a + b; \ *(r++) = b = ind32(mm,y>>RANDSIZL) + x; \ } #define mix32(a,b,c,d,e,f,g,h) \ { \ a^=b<<11; d+=a; b+=c; \ b^=c>>2; e+=b; c+=d; \ c^=d<<8; f+=c; d+=e; \ d^=e>>16; g+=d; e+=f; \ e^=f<<10; h+=e; f+=g; \ f^=g>>4; a+=f; g+=h; \ g^=h<<8; b+=g; h+=a; \ h^=a>>9; c+=h; a+=b; \ } static void isaac32(randctx *ctx) { register ub4 a, b, x, y, *m, *mm, *m2, *r, *mend; mm = ctx->mm; r = ctx->seed; a = ctx->aa; b = ctx->bb + (++ctx->cc); for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; ) { rngstep32( a<<13, a, b, mm, m, m2, r, x); rngstep32( a>>6 , a, b, mm, m, m2, r, x); rngstep32( a<<2 , a, b, mm, m, m2, r, x); rngstep32( a>>16, a, b, mm, m, m2, r, x); } for (m2 = mm; m2<mend; ) { rngstep32( a<<13, a, b, mm, m, m2, r, x); rngstep32( a>>6 , a, b, mm, m, m2, r, x); rngstep32( a<<2 , a, b, mm, m, m2, r, x); rngstep32( a>>16, a, b, mm, m, m2, r, x); } ctx->bb = b; ctx->aa = a; } #define gen_rand32(r) \ (!(r)->randcnt-- ? \ (isaac32(r), (r)->randcnt=RANDSIZ-1, (r)->seed[(r)->randcnt]) : \ (r)->seed[(r)->randcnt]) void rand_init(randctx *ctx, word time_as_seed) { word i; ub4 a, b, c, d, e, f, g, h; ub4 *m, *r; ctx->aa = ctx->bb = ctx->cc = 0; m = ctx->mm; r = ctx->seed; a = b = c = d = e = f = g = h = isaac_golden_ratio32; /* the golden ratio */ /* init seed */ for (i=0; i<256; ++i) { r[i] = (ub4) (time_as_seed? time(0) : 0); } for (i=0; i<4; ++i) { /* scramble it */ mix32(a,b,c,d,e,f,g,h); } if (1) { /* initialize using the contents of r[] as the seed */ for (i=0; i<RANDSIZ; i+=8) { a+=r[i ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3]; e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7]; mix32(a,b,c,d,e,f,g,h); m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d; m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h; } /* do a second pass to make all of the seed affect all of m */ for (i=0; i<RANDSIZ; i+=8) { a+=m[i ]; b+=m[i+1]; c+=m[i+2]; d+=m[i+3]; e+=m[i+4]; f+=m[i+5]; g+=m[i+6]; h+=m[i+7]; mix32(a,b,c,d,e,f,g,h); m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d; m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h; } } else { /* Never run to this: fill in m[] with messy stuff */ for (i=0; i<RANDSIZ; i+=8) { mix32(a,b,c,d,e,f,g,h); m[i ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d; m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h; } } isaac32(ctx); /* fill in the first set of results */ ctx->randcnt = RANDSIZ; /* prepare to use the first set of results */ } /** * randint * get 32-bits unsigned integer random */ ub4 rand(randctx *r) { return gen_rand32(r); } /** * randint * get integer random between rmin and rmax */ ub4 randint(randctx *r, ub4 rmin, ub4 rmax) { if (! r->randcnt-- ) { isaac32(r); r->randcnt = RANDSIZ - 1; } ub4 ret = (ub4) r->seed[r->randcnt]; return ret % (ub4) (rmax - rmin + 1) + rmin; } /** *============================================================================== * 64 bits int random generator *============================================================================== */ #define isaac_golden_ratio64 0x9e3779b97f4a7c13LL #define ind64(mm,x) (*(ub8 *)((ub1 *)(mm) + ((x) & ((RANDSIZ-1)<<3)))) #define rngstep64(mix,a,b,mm,m,m2,r,x) \ { \ x = *m; \ a = (mix) + *(m2++); \ *(m++) = y = ind64(mm,x) + a + b; \ *(r++) = b = ind64(mm,y>>RANDSIZL) + x; \ } #define mix64(a,b,c,d,e,f,g,h) \ { \ a-=e; f^=h>>9; h+=a; \ b-=f; g^=a<<9; a+=b; \ c-=g; h^=b>>23; b+=c; \ d-=h; a^=c<<15; c+=d; \ e-=a; b^=d>>14; d+=e; \ f-=b; c^=e<<20; e+=f; \ g-=c; d^=f>>17; f+=g; \ h-=d; e^=g<<14; g+=h; \ } static void isaac64(randctx64 *ctx) { register ub8 a,b,x,y,*m,*mm,*m2,*r,*mend; mm = ctx->mm; r = ctx->seed; a = ctx->aa; b = ctx->bb + (++ctx->cc); for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; ) { rngstep64(~(a^(a<<21)), a, b, mm, m, m2, r, x); rngstep64( a^(a>>5) , a, b, mm, m, m2, r, x); rngstep64( a^(a<<12) , a, b, mm, m, m2, r, x); rngstep64( a^(a>>33) , a, b, mm, m, m2, r, x); } for (m2 = mm; m2<mend; ) { rngstep64(~(a^(a<<21)), a, b, mm, m, m2, r, x); rngstep64( a^(a>>5) , a, b, mm, m, m2, r, x); rngstep64( a^(a<<12) , a, b, mm, m, m2, r, x); rngstep64( a^(a>>33) , a, b, mm, m, m2, r, x); } ctx->bb = b; ctx->aa = a; } #define gen_rand64(r) \ (!(r)->randcnt-- ? (isaac64(r), (r)->randcnt=RANDSIZ-1, (r)->seed[(r)->randcnt]) : \ (r)->seed[(r)->randcnt]) void rand64_init(randctx64 *ctx, word time_as_seed) { word i; ub8 a,b,c,d,e,f,g,h; ub8 *mm, *r; ctx->aa = ctx->bb = ctx->cc = (ub8) 0; a=b=c=d=e=f=g=h= isaac_golden_ratio64; /* the golden ratio */ mm = ctx->mm; r = ctx->seed; /* init seed */ for (i=0; i<256; ++i) { r[i] = (ub8) (time_as_seed? time(0) : 0); } for (i=0; i<4; ++i) { /* scramble it */ mix64(a,b,c,d,e,f,g,h); } for (i=0; i<RANDSIZ; i+=8) { /* fill in mm[] with messy stuff */ if (1) { /* use all the information in the seed */ a+=r[i ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3]; e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7]; } mix64(a,b,c,d,e,f,g,h); mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; } if (1) { /* do a second pass to make all of the seed affect all of mm */ for (i=0; i<RANDSIZ; i+=8) { a+=mm[i ]; b+=mm[i+1]; c+=mm[i+2]; d+=mm[i+3]; e+=mm[i+4]; f+=mm[i+5]; g+=mm[i+6]; h+=mm[i+7]; mix64(a,b,c,d,e,f,g,h); mm[i ]=a; mm[i+1]=b; mm[i+2]=c; mm[i+3]=d; mm[i+4]=e; mm[i+5]=f; mm[i+6]=g; mm[i+7]=h; } } isaac64(ctx); /* fill in the first set of results */ ctx->randcnt = RANDSIZ; /* prepare to use the first set of results */ } /** * rand64 * get 64-bits unsigned integer random */ ub8 rand64(randctx64 *r) { return (ub8) (gen_rand64(r)); } /** * randint64 * get 64-bits unsigned integer random */ ub8 randint64(randctx64 *r, ub8 rmin, ub8 rmax) { if (! r->randcnt-- ) { isaac64(r); r->randcnt = RANDSIZ - 1; } ub8 ret = (ub8) r->seed[r->randcnt]; return ret % (ub8) (rmax - rmin + 1) + rmin; } #ifdef NEVER static void inner_test32() { ub4 i,j; randctx ctx; rand_init(&ctx, RAND_FALSE); for (i=0; i<2; ++i) { isaac32(&ctx); for (j=0; j<256; ++j) { printf("%.8lx",ctx.seed[j]); if ((j&7)==7) { printf("\n"); } } } } static void inner_test64() { ub8 i,j; randctx64 ctx; rand64_init(&ctx, RAND_FALSE); for (i=0; i<2; ++i) { isaac64(&ctx); for (j=0; j<RANDSIZ; ++j) { printf("%.8lx%.8lx",(ub4)(ctx.seed[j]>>32),(ub4)ctx.seed[j]); if ((j&3)==3) { printf("\n"); } } } } static void usage() { int i; randctx ctx; randctx64 ctx64; rand_init(&ctx, RAND_TRUE); rand64_init(&ctx64, RAND_TRUE); for (i=0; i<100; ++i) { printf("%03d: %d\n", i, (sb4)randint(&ctx, -100, 100)); printf("%03d: %lld\n", i, (sb8)randint64(&ctx64, -100, 100)); } } int main() { inner_test32(); inner_test64(); usage(); } #endif
C语言生成32位和64位随机数算法的更多相关文章
- 64位主机64位oracle下装32位客户端ODAC(NFPACS版)
64位主机64位oracle下装32位客户端ODAC(NFPACS版) by dd 1.下载Oracle Data Access Components(ODAC) Xcopy的两个版本: x86:(我 ...
- Linux系统查看系统是32位还是64位方法总结
这篇博客是总结.归纳查看Linux系统是32位还是64位的一些方法,很多内容来自网上网友的博客.本篇只是整理.梳理这方面的知识,方便自己忘记的时候随时查看. 方法1:getconf LONG_BIT ...
- oracle 32位导64位
oracle 32位导64位 SHUTDOWN IMMEDIATE; STARTUP MOUNT; ALTER SYSTEM ENABLE RESTRICTED SESSION; ; ; ALTER ...
- Shell脚本中,如何判断Linux系统是32位还是64位?
一行就能搞定,输出32或者64 可以用“和. 参考代码如下: ldconfig if [ $(getconf WORD_BIT) = '32' ] && [ $(getconf LON ...
- 【转】Tomcat版本是32位、64位问题
转载地址:http://www.cnblogs.com/greensleeves/p/3168541.html 最近遇到一个Tomcat windows安装版本是32位还是64位问题.由于一系列原因, ...
- 查看Linux是32位还是64位
最直接简洁的办法: 在linux终端输入getconf LONG_BIT命令 如果是32位机器,则结果为32 [root@localhost ~]# getconf LONG_BIT 32 如果是64 ...
- Windows2003 IIS6.0支持32位和64位两种模式的设置方法
IIS 6.0 可支持 32 位和 64 位两种模式.但是,IIS 6.0 不支持在 64 位版本的 Windows 上同时运行这两种模式.ASP.NET 1.1 只在 32 位模式下运行.而 ASP ...
- linux-查看系统是32位还是64位
可以用命令“getconf LONG_BIT”查看, 如果返回的结果是32则说明是32位,返回的结果是64则说明是64位. 此外还可以使用命令“uname -a”查看, 输出的结果中,如果有x86_6 ...
- 查看linux机器是32位还是64位的方法
file /sbin/init 或者 file /bin/ls/sbin/init: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dyna ...
随机推荐
- Latex 文本编辑技巧
临时取消首行缩进 \noindent 生成随机文本 \usepackage{lipsum} \begin{document} \lipsum \end{document} 多栏模式 \usepacka ...
- Dynamics CRM 删除字段时检测到有组件类型为查看的依赖组件而无法删除问题
今天在删除一个字段的时候报如下截图错误,点开详细信息会看到是一个快速查找视图,但却在视图列中没有找到我要删的那个字段,然后回过头来又看到组件类型是查看,这是啥类型?有点摸不着头脑了. 最后想到是不是查 ...
- java项目管理工具maven使用初级
一.前言 早就知道maven 在java 项目的管理方面名声显赫,于是就想着学习掌握之,于是查阅了大量文档.发现这些文档的作者都是java 的大腕,大多都是站在掌握了一定maven 基础 ...
- [ExtJS5学习笔记]第二十五节 利用window.open()函数实现ExtJS5的登陆页面跳转
本文地址:http://blog.csdn.net/sushengmiyan/article/details/40427543 mvvm方式实现登陆的博客:http://blog.csdn.net/s ...
- Linux2.6 --系统调用处理程序
用户空间的程序无法直接执行内核代码.它们不能直接调用内核空间中的函数,因为内核驻留在受保护的地址空间上.如果进程可以直接在内核的地址空间上读写的话,系统的安全性和稳定性将不复存在. ...
- Android的RadioButton和checkBox的用法-android学习之旅(十九)
RadioButton和checkBox简介 单选按钮(RadioButton)和复选框(CheckBox)都继承了Button,因此属性的设置和Button差不多,只是加了一个android:che ...
- Transform介绍(Unity3D开发之二)
猴子原创,欢迎转载.转载请注明: 转载自Cocos2D开发网–Cocos2Dev.com,谢谢! 原文地址: http://www.cocos2dev.com/?p=491 可能unity中接触较早的 ...
- android 使用Vysor投影到电脑
有没有好的投影软件可以将android屏幕投影到电脑,当然这种很多,比如360就自带了投影功能,小米盒子也可以(不过貌似只能支持到4.4版本),今天要说的是Vysor,google的一款投影软件. V ...
- (一一七)基本文件操作 -SDWebImage清除缓存 -文件夹的大小计算
在iOS的App沙盒中,Documents和Library/Preferences都会被备份到iCloud,因此只适合放置一些记录文件,例如plist.数据库文件.缓存一般放置到Library/Cac ...
- Postgre: How to import UUID function into Postgre 9.3
1. Open a command console and go to the directory where you installed Postgre server. e.g. D:\Progra ...