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
时间: 2024-10-28 23:08:36

C语言生成32位和64位随机数算法的相关文章

iOS 32位、 64位系统兼容性设置-Xcode创建支持IOS4.3以上版本的应用的方法

方法一: 如果是Xcode 5的话步骤为 点击项目名称->Build Settings->搜索 Architectures 这个里面的原始的值是Standard architectures(armv7,armv7s,arm64) 点击这个值,在下拉列表框中选择 Standard architectures(armv7,armv7s) ,然后保存项目,转到 General里面去就可以看到项目的Target选项里面会从4.3到7.0都有. 如果是Xcode 5.1的话步骤为 点击项目名称->

CentOS 5 上使用yum同时安装32位和64位包的解决方法

在centos上使用yum在线安装软件包的时候,有时候会同时安装32位和64位的包.并且在update的时候也会更新双份. 其实让yum只安装64位的包,只要在 /etc/yum.conf 中加个 exclude 选项: [main] cachedir=/var/cache/yum keepcache=0 plugins=1 ...... exclude=*.i?86 exclude 选项支持正则表达式,*.i?86可以用来过滤掉i386,i686等32bit包. 如果要删除已经安装的32bit

驱动级多开工具,支持32位和64位

标题:[原创]驱动级多开工具,支持32位和64位 作者:绿林科技 时间:2015-5-16 链接:http://blog.csdn.net/o6108/article/details/47790019 作者QQ:1473656864 技术交流群1:177822108 技术交流群2:177822398 通用驱动级多开器,可多开市面上的90%的程序. PS:本来想弄个收费版本的,后来想了想,决定弄成免费.店铺为更新软件版本用的. 软件的About页面有我的QQ和Q群号,请大家把使用过程中遇到的BUG

如何查看eclipse是32位还是64位

如何查看eclipse是32位还是64位? 1.如果是在官网下载的,看压缩包名字就可以看出来,只带有win32字样的是32位,带有win32-x86_64字样的是64位的. 如果已经安装了很多,安装包已经找不到了怎么办呢? 2.找到eclipse安装目录的eclipse.ini文件打开,在launcher.library项下,如果是win32.x86则是32位的,如果是win32.x86_64则是64位的. -startup plugins/org.eclipse.equinox.launche

iOS-程序发布-32位和64位系统的兼容

在苹果推出iPhone5S时,64位的应用就走到了眼前.当时就看见苹果官方资料宣布iOS7.x的SDK支持了64位的应用,而且内置的应用都已经是64位. 我记得自己刚刚接触电脑时还有16位的系统,指针的寻址范围还是16位的.当年用TurboC时,还要根据应用的大小选择是tiny模式还是其他.后来很长一段时间使用32位的模型编程,4G是牢牢记住的一个边界条件.而现在,64位走到了眼前. 就如同16位转向32位一样,硬件肯定是最先推出的,SDK也会跟进,然后各种第三方的应用才会逐步跟进,这个过程一般

Photoshop CS6最新官方正式中文破解版(32位、64位)

Photoshop是强大的图形处理软件,在前端开发领域中,主要用于页面的图形设计与网站UI切图. 目前最新版为Adobe Photoshop CS6 在CS6中整合了其Adobe专有的 Mercury图像引擎,通过显卡核心GPU提供了强悍的图片编辑能力. 但是相对于CS5来说,操作上发生了一定程度的变化,所以建议使用时仔细查看说明文档. 此次提供的版本为官方正式中文版,非汉化版.精简版.绿色版.包含Photoshop CS6中的所有组件与素材. 安装时请断开网络,并选择安装试用版.待软件全部安装

iis6.0 32为和64位的切换

简介 更多信息 ASP.NET 1.1(32 位版) ASP.NET 2.0(32 位版) ASP.NET 2.0(64 位版) 基于 x64 版本 Microsoft Windows 的技术支持 参考 属性 提供反馈 简介 本文讨论如何在 64 位版本的 Microsoft Windows 上,在 32 位版本的 Microsoft ASP.NET 1.1 和 32 位及 64 位版本的 ASP.NET 2.0 之间切换. 当您同时安装了这两个版本的 ASP.NET 时,如果没有使这两个 AS

hadoop2.5发布:最新编译 32位、64位安装、源码包、API以及新特性

hadoop2.5发布:最新编译 32位.64位安装.源码包.API以及新特性 http://www.aboutyun.com/thread-8751-1-1.html (出处: about云开发) 问题导读:1.如何获取Hadoop安装包?2.编译Hadoop过程中,需要注意哪些问题?3.如何寻找API?4.如何获取Hadoop源码? 上述问题有的在本文,有的则在本文链接,感兴趣,可以找找答案 2014年08月06日 Hadoop2.5发布 官网下载地址 对Hadoop2.5进行了编译,编译的

Win7系统32位和64位有什么区别?

32位与64位系统的区别与联系,已经是一个老生常谈的问题了,下面我深入的给同学们介绍下Win7系统32位和64位的区别与联系,大家不太懂的地方可以问度娘.另外还有一部分朋友会问XP或者Win8系统32位与64位的区别,其实跟Win7都是一样的. Win7系统32位和64位的区别 对于目前来说,绝大多数软件以32位开发为主,当然也开始有越来越多应用采用64位设计,对于一般用户而言,不管是32位还是64位系统,其实使用上差别基本感受不到,因此一般我们无需纠结于到底是选择32位还是64位Win7系统.