Rand.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:3k
源码类别:

P2P编程

开发平台:

Visual C++

  1. /*
  2. ------------------------------------------------------------------------------
  3. rand.c: By Bob Jenkins.  My random number generator, ISAAC.  Public Domain.
  4. MODIFIED:
  5.   960327: Creation (addition of randinit, really)
  6.   970719: use context, not global variables, for internal state
  7.   980324: added main (ifdef'ed out), also rearranged randinit()
  8.   010626: Note that this is public domain
  9. ------------------------------------------------------------------------------
  10. */
  11. #include "rand.h"
  12. #define ind(mm,x)  (*(ub4 *)((ub1 *)(mm) + ((x) & ((RANDSIZ-1)<<2))))
  13. #define rngstep(mix,a,b,mm,m,m2,r,x) 
  14.   x = *m;  
  15.   a = (a^(mix)) + *(m2++); 
  16.   *(m++) = y = ind(mm,x) + a + b; 
  17.   *(r++) = b = ind(mm,y>>RANDSIZL) + x; 
  18. }
  19. void  isaac(randctx *ctx)
  20. {
  21.    register ub4 a,b,x,y,*m,*mm,*m2,*r,*mend;
  22.    mm=ctx->randmem; r=ctx->randrsl;
  23.    a = ctx->randa; b = ctx->randb + (++ctx->randc);
  24.    for (m = mm, mend = m2 = m+(RANDSIZ/2); m<mend; )
  25.    {
  26.       rngstep( a<<13, a, b, mm, m, m2, r, x);
  27.       rngstep( a>>6 , a, b, mm, m, m2, r, x);
  28.       rngstep( a<<2 , a, b, mm, m, m2, r, x);
  29.       rngstep( a>>16, a, b, mm, m, m2, r, x);
  30.    }
  31.    for (m2 = mm; m2<mend; )
  32.    {
  33.       rngstep( a<<13, a, b, mm, m, m2, r, x);
  34.       rngstep( a>>6 , a, b, mm, m, m2, r, x);
  35.       rngstep( a<<2 , a, b, mm, m, m2, r, x);
  36.       rngstep( a>>16, a, b, mm, m, m2, r, x);
  37.    }
  38.    ctx->randb = b; ctx->randa = a;
  39. }
  40. #define mix(a,b,c,d,e,f,g,h) 
  41.    a^=b<<11; d+=a; b+=c; 
  42.    b^=c>>2;  e+=b; c+=d; 
  43.    c^=d<<8;  f+=c; d+=e; 
  44.    d^=e>>16; g+=d; e+=f; 
  45.    e^=f<<10; h+=e; f+=g; 
  46.    f^=g>>4;  a+=f; g+=h; 
  47.    g^=h<<8;  b+=g; h+=a; 
  48.    h^=a>>9;  c+=h; a+=b; 
  49. }
  50. /* if (flag==TRUE), then use the contents of randrsl[] to initialize mm[]. */
  51. void randinit(
  52. randctx *ctx, 
  53. word     flag)
  54. {
  55.    word i;
  56.    ub4 a,b,c,d,e,f,g,h;
  57.    ub4 *m,*r;
  58.    ctx->randa = ctx->randb = ctx->randc = 0;
  59.    m=ctx->randmem;
  60.    r=ctx->randrsl;
  61.    a=b=c=d=e=f=g=h=0x9e3779b9;  /* the golden ratio */
  62.    for (i=0; i<4; ++i)          /* scramble it */
  63.    {
  64.      mix(a,b,c,d,e,f,g,h);
  65.    }
  66.    if (flag) 
  67.    {
  68.      /* initialize using the contents of r[] as the seed */
  69.      for (i=0; i<RANDSIZ; i+=8)
  70.      {
  71.        a+=r[i  ]; b+=r[i+1]; c+=r[i+2]; d+=r[i+3];
  72.        e+=r[i+4]; f+=r[i+5]; g+=r[i+6]; h+=r[i+7];
  73.        mix(a,b,c,d,e,f,g,h);
  74.        m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
  75.        m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
  76.      }
  77.      /* do a second pass to make all of the seed affect all of m */
  78.      for (i=0; i<RANDSIZ; i+=8)
  79.      {
  80.        a+=m[i  ]; b+=m[i+1]; c+=m[i+2]; d+=m[i+3];
  81.        e+=m[i+4]; f+=m[i+5]; g+=m[i+6]; h+=m[i+7];
  82.        mix(a,b,c,d,e,f,g,h);
  83.        m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
  84.        m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
  85.      }
  86.    }
  87.    else
  88.    {
  89.      /* fill in m[] with messy stuff */
  90.      for (i=0; i<RANDSIZ; i+=8)
  91.      {
  92.        mix(a,b,c,d,e,f,g,h);
  93.        m[i  ]=a; m[i+1]=b; m[i+2]=c; m[i+3]=d;
  94.        m[i+4]=e; m[i+5]=f; m[i+6]=g; m[i+7]=h;
  95.      }
  96.    }
  97.    isaac(ctx);            /* fill in the first set of results */
  98.    ctx->randcnt=RANDSIZ;  /* prepare to use the first set of results */
  99. }
  100. #ifdef NEVER
  101. int main()
  102. {
  103.   ub4 i,j;
  104.   randctx ctx;
  105.   ctx.randa=ctx.randb=ctx.randc=(ub4)0;
  106.   for (i=0; i<256; ++i) ctx.randrsl[i]=(ub4)0;
  107.   randinit(&ctx, TRUE);
  108.   for (i=0; i<2; ++i)
  109.   {
  110.     isaac(&ctx);
  111.     for (j=0; j<256; ++j)
  112.     {
  113.       printf("%.8lx",ctx.randrsl[j]);
  114.       if ((j&7)==7) printf("n");
  115.     }
  116.   }
  117. }
  118. #endif