考虑到很多人还在用古老的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] );
    
}