考虑到很多人还在用古老的srand( time(NULL) )和rand(),这在密码学里面是很不安全也很不科学的,推荐OS自己的cryptAPI,其中Windows有API,在Linux下面可以使用OpenSSL的库,先发一个Windows的Cpp封装,支持简单的RAII,随后贴出来Linux下的。

程序里面偷懒了,本来初始化和释放CSP失败应该抛出异常,图省事就写了个printf,请大家多多提意见

WinRandom.h

#ifndef WIN_RANDOM_H_
#define  WIN_RANDOM_H_

#include 
< windows.h >

namespace  triod
{
    
class  WinRandom
    {
    
public :
        WinRandom();
        
~ WinRandom();
        unsigned 
char  random_char();
        unsigned 
short  random_short();
        unsigned 
long  random_long();
        unsigned 
long  set_random_char( unsigned  char *  memory, unsigned  long  size );
    
private :
        HCRYPTPROV crypt_prov_;
    };
}

#endif

WinRandom.cpp
#include  < stdio.h >
#include 
" winRandom.h "

#pragma comment(lib, 
" advapi32.lib " )

namespace  triod
{
    WinRandom::WinRandom() : crypt_prov_( NULL )
    {
        
if ! CryptAcquireContext(  & crypt_prov_, NULL, NULL, PROV_RSA_FULL,  0 ) ) 
        {
            
if ! CryptAcquireContext(  & crypt_prov_, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET) ) 
                printf(
" CryptAcquireContext Failed. \n " );
        }
    }
        
    WinRandom::
~ WinRandom()
    {
        
if ( crypt_prov_ )
        {
            
if  (  ! CryptReleaseContext(crypt_prov_,  0 ) )
                printf( 
" Failed CryptReleaseContext\n "  );
        }
    }

    unsigned 
char  WinRandom::random_char()
    {
        BYTE data[
sizeof (unsigned  char )];
        unsigned 
char  r  =   0 ;
        
        
if ( crypt_prov_ )
        {
            
if ( CryptGenRandom( crypt_prov_,  sizeof (data), data) ) 
            {
                memcpy( 
& r, data,  sizeof (data) );
            }
        }

        
return  r;    
    }

    unsigned 
short  WinRandom::random_short()
    {
        BYTE data[
sizeof (unsigned  short )];
        unsigned 
short  r  =   0 ;
        
        
if ( crypt_prov_ )
        {
            
if ( CryptGenRandom( crypt_prov_,  sizeof (data), data) ) 
            {
                memcpy( 
& r, data,  sizeof (data) );
            }
        }

        
return  r;    
    }

    unsigned 
long  WinRandom::random_long()
    {
        BYTE data[
sizeof (unsigned  long )];
        unsigned 
long  r  =   0 ;
        
        
if ( crypt_prov_ )
        {
            
if ( CryptGenRandom( crypt_prov_,  sizeof (data), data) ) 
            {
                memcpy( 
& r, data,  sizeof (data) );
            }
        }

        
return  r;
    }

    unsigned 
long  WinRandom::set_random_char( unsigned  char *  memory, unsigned  long  size )
    {
        
if ( crypt_prov_ )
        {
            
if ! CryptGenRandom( crypt_prov_, size, memory) ) 
                
return   0 ;
        }
        
        
return  size;
    }
}



test.cpp

#include  " winRandom.h "
#include 
< stdio.h >
    
int  main()
{
    
using  triod::WinRandom;
    
    WinRandom test;
    
    
for  ( size_t i  =   0 ; i  <   100 ++ i )
        printf( 
" %02x  " , test.random_char() );
    printf( 
" \n "  );
    
    
for  ( size_t i  =   0 ; i  <   100 ++ i )
        printf( 
" %04x  " , test.random_short() );
    printf( 
" \n "  );
    
    
for  ( size_t i  =   0 ; i  <   100 ++ i )
        printf( 
" %08x  " , test.random_long() );
    printf( 
" \n "  );
    
    unsigned 
char  roman[ 1000 ];
    test.set_random_char( roman, 
1000  );

    
for  ( size_t i  =   0 ; i  <   1000 ++ i )
        printf( 
" %02x  " , roman[i] );
    
}