请教一个,随机产生不重复字符串的问题

时间:2022-01-08 22:30:42
大概需要100W个不重复的字符串,请教下思路,谢谢,有相应例子更好

20 个解决方案

#1


有那么多字符?

#2


包括中文么?

#3


数字和英语,即可,关键是绝对不能有重复,算法里写死,因为不可能每次去判断,这样计算量太大了

#4


原理和GUID生成差不多

#5


楼上的能详细说下吗?谢谢

#6


字符串位数不限,但要统一,希望大家帮忙出出主义,谢谢

#7


随机而且不重复,而且还有序?

具体什么用处?

字符串序列生成不可以?

#8


用来当做序列号用的,所以不希望被人家拿到一个号,就能猜出另外全部的

#9


数字+大小写字母一共有62个。
62的3次方是238328,4次方是14776336。
所以你的字符串至少得有4位。
可以按照我在这篇帖子中给出的方法:
http://topic.csdn.net/u/20070930/11/4fbc99f5-3c48-48a1-8a75-f6cdb54a3191.html
把100W种情况分散到前4位字符中去,也可以分散到更多位,关键看你想要多长的字符串。方案可自己设计。
例如:先把前3位作一次全排列就有238328多种了,第4位划分出5个区间,第4位每次在不同区间中抽取,后面的字符完全随机就可以不重复了。这样就有238328*5=1191640种情况了,保证没有一个重复的。

#10


楼上的,我爱你,我去研究研究

#11


mark一下
看起来很有用,

我来块砖,有玉的准备好

怎么听起来跟编码差不多
假定用这些,
0-9和26个字母,共36个字符,(一般做序列号的字母都大写)
一位就是36的一次方,
....
3位数是4万多
4位数是160多万
....4位编码就足够了

需要做的就是把这些码对应上实际数字

虽然4位编码就足够了,但这太少了,很容易被试出来,
作序列号至少要10几位吧,实际将这些随即序列数挑出来,
这个很容易,用随即数生成器规定好范围就可以。

将其记录下来,按36进制编码就可得到合法序列号。
再用某种算法加密,密钥是用户提供的用户名。可作激活码用

随机而且不重复,而且还有序
要有序那可能使过程简单些,

呵呵,深夜随想,可能不实用。

#12


产生一个6位数的随机数可以么?

#13


这个其实很简单,不要想随机,这样肯定有重复的问题,可以使用排序的方法。

楼上的几位都说了,把所有的数排序就好了。

100W不多,你可以产生1000W个已经排好序的字符串,
然后随机从里面取100W个。

这个时候可以产生随机数,如果重复的就不算了,重新再取。

要增加随机性,可以分段排序。

需要多少位,基本上5位一个序列,差不多

26^5 * 5 这样随机性就很好了

#14


CoCreateGuid

#15


CTime time== CTime::GetCurrentTime();//取时间
CString t=time.Format()//换成字符串
MD5.get()//用MD5算法对该字符串生成指纹,该指纹是128位的,您把这128位用16进制表示出来,就是一个32字符
的字符串,重复的概率几乎是0

#16


MD5算法符合你的要求(唯一且位数一致),类似的数学算法很多

#17


很简单的
  
__int64 i1=0;
__int64 i2=0;
unsigned __int32 dw=0;
unsigned __int32 irandom;

int  imaxlength;

static const int imax=1000000; //change it for your self
char buffer[1024];
memset(buffer,0,1024);
int j,k;
for(int i=0;i<imax;i++)
{
   imaxlength=i%512+16; //假设你要求的字符串长度为16个字符到16+512个字符长度,因为16个字符用来生成唯一的字符参数
                        
   //现在,我们来产生随即数

   i1++; //这个参数可以确保肯定不会有重复的
   k=sprintf(buffer,"%I64X",i1);//已经用去的缓冲长度//当然,你可以把它放在字符串最后面,稍微修改一下就可以
   buffer[imaxlength]='\0';//结尾必须是0
   dw=GetTickCount( );//随即数字  
   i2+=dw%7;
   if(i2>=0X86543212AABBCC8i64)
   {
    i2=i2/3;
    }

   irandom=dw/(i+37)+(int)(i1%dw);
   //现在生成随机字符串
   for(j=k;i<imaxlength;j++)
   {
    //你自己根据 dw irandom i2 参数来决定如何生成吧
    //一般的方法是采用一个自己的随机函数,来决定生成哪个字符
    //比如
    if(j%7==0)
    buffer[j]='a'+i2%26;
   }
   //好了,生成完毕,你自己的函数去保存参数吧
   //m_array.push(buffer,imaxlength);
   
}//end for

#18


修改一下,
忘记加限制参数了
k=sprintf(buffer,"%16I64X",i1);

#19


可以将系统时间前缀或后缀,精确到微秒;在结合其他的方法,应该不会重复的

#20


非常感觉楼上几位的教导,我在这拜谢了

#1


有那么多字符?

#2


包括中文么?

#3


数字和英语,即可,关键是绝对不能有重复,算法里写死,因为不可能每次去判断,这样计算量太大了

#4


原理和GUID生成差不多

#5


楼上的能详细说下吗?谢谢

#6


字符串位数不限,但要统一,希望大家帮忙出出主义,谢谢

#7


随机而且不重复,而且还有序?

具体什么用处?

字符串序列生成不可以?

#8


用来当做序列号用的,所以不希望被人家拿到一个号,就能猜出另外全部的

#9


数字+大小写字母一共有62个。
62的3次方是238328,4次方是14776336。
所以你的字符串至少得有4位。
可以按照我在这篇帖子中给出的方法:
http://topic.csdn.net/u/20070930/11/4fbc99f5-3c48-48a1-8a75-f6cdb54a3191.html
把100W种情况分散到前4位字符中去,也可以分散到更多位,关键看你想要多长的字符串。方案可自己设计。
例如:先把前3位作一次全排列就有238328多种了,第4位划分出5个区间,第4位每次在不同区间中抽取,后面的字符完全随机就可以不重复了。这样就有238328*5=1191640种情况了,保证没有一个重复的。

#10


楼上的,我爱你,我去研究研究

#11


mark一下
看起来很有用,

我来块砖,有玉的准备好

怎么听起来跟编码差不多
假定用这些,
0-9和26个字母,共36个字符,(一般做序列号的字母都大写)
一位就是36的一次方,
....
3位数是4万多
4位数是160多万
....4位编码就足够了

需要做的就是把这些码对应上实际数字

虽然4位编码就足够了,但这太少了,很容易被试出来,
作序列号至少要10几位吧,实际将这些随即序列数挑出来,
这个很容易,用随即数生成器规定好范围就可以。

将其记录下来,按36进制编码就可得到合法序列号。
再用某种算法加密,密钥是用户提供的用户名。可作激活码用

随机而且不重复,而且还有序
要有序那可能使过程简单些,

呵呵,深夜随想,可能不实用。

#12


产生一个6位数的随机数可以么?

#13


这个其实很简单,不要想随机,这样肯定有重复的问题,可以使用排序的方法。

楼上的几位都说了,把所有的数排序就好了。

100W不多,你可以产生1000W个已经排好序的字符串,
然后随机从里面取100W个。

这个时候可以产生随机数,如果重复的就不算了,重新再取。

要增加随机性,可以分段排序。

需要多少位,基本上5位一个序列,差不多

26^5 * 5 这样随机性就很好了

#14


CoCreateGuid

#15


CTime time== CTime::GetCurrentTime();//取时间
CString t=time.Format()//换成字符串
MD5.get()//用MD5算法对该字符串生成指纹,该指纹是128位的,您把这128位用16进制表示出来,就是一个32字符
的字符串,重复的概率几乎是0

#16


MD5算法符合你的要求(唯一且位数一致),类似的数学算法很多

#17


很简单的
  
__int64 i1=0;
__int64 i2=0;
unsigned __int32 dw=0;
unsigned __int32 irandom;

int  imaxlength;

static const int imax=1000000; //change it for your self
char buffer[1024];
memset(buffer,0,1024);
int j,k;
for(int i=0;i<imax;i++)
{
   imaxlength=i%512+16; //假设你要求的字符串长度为16个字符到16+512个字符长度,因为16个字符用来生成唯一的字符参数
                        
   //现在,我们来产生随即数

   i1++; //这个参数可以确保肯定不会有重复的
   k=sprintf(buffer,"%I64X",i1);//已经用去的缓冲长度//当然,你可以把它放在字符串最后面,稍微修改一下就可以
   buffer[imaxlength]='\0';//结尾必须是0
   dw=GetTickCount( );//随即数字  
   i2+=dw%7;
   if(i2>=0X86543212AABBCC8i64)
   {
    i2=i2/3;
    }

   irandom=dw/(i+37)+(int)(i1%dw);
   //现在生成随机字符串
   for(j=k;i<imaxlength;j++)
   {
    //你自己根据 dw irandom i2 参数来决定如何生成吧
    //一般的方法是采用一个自己的随机函数,来决定生成哪个字符
    //比如
    if(j%7==0)
    buffer[j]='a'+i2%26;
   }
   //好了,生成完毕,你自己的函数去保存参数吧
   //m_array.push(buffer,imaxlength);
   
}//end for

#18


修改一下,
忘记加限制参数了
k=sprintf(buffer,"%16I64X",i1);

#19


可以将系统时间前缀或后缀,精确到微秒;在结合其他的方法,应该不会重复的

#20


非常感觉楼上几位的教导,我在这拜谢了

#21