前一篇文章 产生随机字符所使用的随机种子是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);