vc产生随机字符 二

前一篇文章 产生随机字符所使用的随机种子是srand,这里使用另一种方法:使用QueryPerformanceCounter函数输出参数作为随机种子,因为QueryPerformanceCounte是计算当前运行的时间计数,前后调用这个函数会得到不同的值,利用后面的值减去前面的值,得到差即可作为种子。

实现:

  WORD __stdcall wRand2(){
    /*产生随机数(word)*/
    //1.循环次数---不大于1000的次数
    //2.取最后一个的值word
    LARGE_INTEGER li;
    QueryPerformanceCounter (&li);
    int icount=li.QuadPart%1000;
    for(int i =0;i<icount;i++)
        QueryPerformanceCounter (&li);
    return li.QuadPart%USHORT_MAX;
    }
上面算法是首先得到QueryPerformanceCounter的时间计数,即 li,然后取它的最高三位的值,用这个值作为循环的次数,然后得到最后一次li的值,%USHORT_MAX,得到不大于0xffff的值,作为种子。

每次产生一个随机种子就需要执行一次在1000以内的循环,这样可以确保QueryPerformanceCounter得到前后的时间计数不一致,因为执行一个1000次的循环,需要消耗一定的计算时间,QueryPerformanceCounter的时间间隔的差异会大些。但是,这样的效率其实不高,如果说,每产生一次随机数,就需要一个随机种子,假设现在需要一个1024的长度随机字符,最不保守的估计,至少需要1024*1000次的计算才可得到,如果在用户界面上等待随机字符的产生,有可能会出现一个等待。。而缺少了实时性。

以下是随机字符产生的函数:

BOOL __stdcall GetRandomString2W(__in  WORD wRandStrFlag,__out LPWSTR  lpbufstr,__in  DWORD buflen){


    using namespace std;

    if(lpbufstr==NULL) return (FALSE);
    PWSTR lpbuf= new WCHAR[buflen];
    vector<WORD> v;
    if(wRandStrFlag==(WORD)RANDOMSTR_FLAG_ALL
        ||wRandStrFlag==0
        /*注意,这里为0也同样于RANDOMSTR_FLAG_ALL */){
            v.push_back(1);//小写字母
            v.push_back(2);//大写字母
            v.push_back(3);//数字
            v.push_back(4);//符号
        }
    else
        {
        if((wRandStrFlag&RANDOMSTR_FLAG_LOWERCASE)
            ==RANDOMSTR_FLAG_LOWERCASE)
            v.push_back(1);//小写字母 1
        if((wRandStrFlag&RANDOMSTR_FLAG_CAPITAL_LETTER)
            ==RANDOMSTR_FLAG_CAPITAL_LETTER)
            v.push_back(2);//大写字母 2
        if((wRandStrFlag&RANDOMSTR_FLAG_NUMBER)
            ==RANDOMSTR_FLAG_NUMBER)
            v.push_back(3);//数字 4
        if((wRandStrFlag&RANDOMSTR_FLAG_PUNCTUATION)
            ==RANDOMSTR_FLAG_PUNCTUATION)
            v.push_back(4);//符号 8
        }

    if(0==v.size()) return(FALSE);//判断
    /*如果字符长度小于6,则为6,最大不大于0xffffffff*/
    if(buflen<6) buflen=6;
    //if(buflen>128) buflen=128;
    WORD lastIndex=v.size();//根据的是上面依次push_back的最后的索引位置,从小到大。
    int flagword=-1;//用于储存被随机选中的wRandstrFlag值
    int index=-1;//在数组中索引值



    for(int i=0;i<(int)buflen;i++){
        //计算选择FLAG
        flagword=(wRand2()+256)%lastIndex;

        flagword=v.at(flagword)-1;
        switch(flagword){
case 0:/*小写字母 */
    index=(wRand2()+256)%26;/*+256表示最小的值为256 */
    //PA(index);
    lpbuf[i]=lowercase[index];
    break;
case 1:/*大写字母 */
    index=(wRand2()+256)%26;
    lpbuf[i]=capital_letter[index];
    break;
case 2:/* 数字*/
    index=(wRand2()+256)%10;
    lpbuf[i]=number[index];
    break;
case 3:/*符号 */
    index=(wRand2()+256)%31;
    lpbuf[i]=punctuation[index];
    break;
            }//switch

        }//for//如果lpbuf溢出
//    lpbuf[buflen]=0;
    lstrcpynW(lpbufstr,lpbuf,buflen);
    v.clear();
    delete[] lpbuf;
    return (TRUE);
    }

 

-----------------------

 

这里是在main的调用

 


WCHAR str2[0xffff];
GetRandomString2W(1,str2,0xffff);
int i =lstrlenW(str);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值