2012-04-19 124 views
0

我已经去过这个网站很多次,并且找到了我的问题的答案,但是最终我发布了一个我自己的问题!所以在我的软件中,一个特定类的目标是生成固定长度的随机密码,由'低'ASCII字符组成。主要的问题是我不想两次生成相同的密码,但始终保证唯一性。最初,我使用了一个HashMap来散列我迄今为止生成的每个密码,并在返回前每次创建一个新的密码时用作检查。但是,Java HashMap对象的大小是有限的,最终Map会变得过饱和,无法维持可接受的检索时间。以下是我对该问题的最新破解:Java中的高效非重复密码生成器

package gen; 

import java.util.Set; 

import java.util.Random; 

import java.util.HashSet; 

public class Generator { 

Random r; 
int length; 
Set<String> seen; 

public Generator(int l){ 
    seen = new HashSet<String>(); 
    length = l; 
    r = new Random(); 
    r.setSeed(System.currentTimeMillis()); 
} 

public String generate(){ 
    String retval = ""; 
    int i = 0; 
    while(i<length){ 
     int rand = r.nextInt(93)+33; 
     if(rand!=96){ 
      retval+= (char)rand; 
      i++; 
     } 
    } 
    return retval; 
} 

public String generateNoRepeat(){ 
    String retval; 
    int i; 
    do{ 
     retval =""; 
     i = 0; 
     while(i<length){ 
      int rand = r.nextInt(93)+33; 
      if(rand!=96){ 
       retval+= (char)rand; 
       i++; 
      } 
     } 
    }while(!seen.add(retval)); 
    return retval; 
} 
} 

编辑:非常感谢设置建议。它现在也使我的代码变得更加清洁!

我可以决定只使用哑生成方法,填补了BlockingQueue,只是其多线程死亡......

进一步澄清:这是不是意味着产生安全的密码。它必须简单地保证它将最终生成所有可能的密码,并且对于给定的长度和字符集只会生成一次。

注:

我已经采取了每个人的见解,并得出这样按顺序产生可能的密码,并将它们存储到磁盘的结论可能是我最好的选择。无论是或者只是允许重复的密码,并补充多个发生器线程的低效率。

+4

您是否知道这种避免重复事件的愿望是[帮助盟军赢得第二次世界大战的纳粹谜团密码系统]的弱点(https://en.wikipedia.org/wiki/Enigma_machine) ? – 2012-04-19 06:08:58

+1

为什么要避免两次生成相同的密码非常重要?只要重复的概率足够低(并且不可预知),就不会有真正的安全性折中。 – 2012-04-19 06:11:57

+0

如果它总是真的,那么在你的Map中使用布尔值是否有任何理由?你可以尝试使用'Set'代替 – MadcoreTom 2012-04-19 06:13:07

回答

1

为什么不只是加密连续数字?

设n是序列中的第一个数字(不要从零开始)。设e是某种加密算法(如RSA)。

那么你的密码是E(N),E(N + 1),E(N + 2),...

但我严重格雷格Hewgill和特德·霍普同意,避免重复是比较麻烦比它值得。

+0

您是否熟悉开发性搜索算法(如字典式攻击)的概念?这就是我所要做的,但我希望每个密码的生成概率仍尽可能接近相等。不过你说得很好。 – Fz3 2012-04-19 06:34:06

+0

我得出的结论是,生成所有可能的密码并将它们存储在磁盘上是一种方法。这样,我需要做的就是跟踪我剩下的人数,并删除我决定每次使用的索引。 – Fz3 2012-04-19 08:23:39