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