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 ...
随机推荐
- 【mybatis深度历险系列】mybatis中的高级映射一对一、一对多、多对多
学习hibernate的时候,小编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博文,小编主要来简单的介绍一下mybatis中的高级映射,包括一对一.一对多.多对多,希望多有需要 ...
- [apache2.4]configure: error: APR not found. Please read the documentation.
apache2.4 安装出现如下错误 ``` [lzz@localhost httpd-2.4.10]$ ./configure checking for chosen layout... Apac ...
- 视频编码器评测系统:VideoCodecRank
视频编码器领域一直有个比较复杂的问题:mpeg2.divx.xvid.mpeg4.vp8.vp9.x264.openh264.x265等等这一系列编码器到底哪个好?而对于同一种视频编码器,又包括了各种 ...
- Android 增量更新和升级
在年初的时候,尝试了一把热修复技术,当时选择的是阿里的andfix,使用起来也很简单,这里就不在多少,如果你对andfix有兴趣请链接:点击打开链接.虽然网上将热修复的文章很多,不过我还是想说原理,然 ...
- iOS开发之音频播放AVAudioPlayer 类的介绍
主要提供以下了几种播放音频的方法: 1. System Sound Services System Sound Services是最底层也是最简单的声音播放服务,调用 AudioServicesPla ...
- UNIX网络编程——线程池模式比较(ICE线程池模型和L/F领导者跟随者模式)
程池模式一般分为两种:L/F领导者与跟随者模式.HS/HA半同步/半异步模式. HS/HA 半同步/ 半异步模式 :分为三层,同步层.队列层.异步层,又称为生产者消费者模式,主线程处理I/O事件并解析 ...
- J2EE进阶(四)Spring配置文件详解
J2EE进阶(四)Spring配置文件详解 前言 Spring配置文件是用于指导Spring工厂进行Bean生产.依赖关系注入(装配)及Bean实例分发的"图纸".Java EE程 ...
- Ubuntu 15.10下的WebStorm-11.0.3完美破解
由于最新的JetBrains 发布了最新版本的IntelliJ IDEA的各个版本,而且更换了注册机的使用方式,这就导致了之前对WebStorm的破解方法不能在使用了.所以我们就必须另寻他法咯.如题, ...
- Cocos2D将v1.0的tileMap游戏转换到v3.4中一例(七)
大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 打开SpriteBuilder,在文件视图中新建一个文件夹Fon ...
- J2EE进阶(二)从零开始之Struts2
J2EE进阶(二)从零开始之Struts2 以前自己总是听说什么SSH框架,不明觉厉.现在自己要重整旗鼓,开始系统性的学习SSH框架了.首先开始Struts2的学习.其实自己之前参与过Struts2项 ...