如何根据一个给定的概率生成一个密码文件?例如:字母a出现的概率为0.8%,我想生成一个密码生成器,在100个密码中字母a的概率要接近0.8%,误差范围要控制在0。05中,各位大虾有什么好的算法提供么?或是有什么资源可以提供参考么?

解决方案 »

  1.   

    http://community.csdn.net/Expert/topic/4183/4183316.xml?temp=.2314264
      

  2.   

    假设现在有数组object[m] (m>=1),他们的号码分别是x1>x2>x3……….>xm
    1. 分别计算x1/(x1+x2+……….+xm),x2/(x1+x2+……….+xm)
    将计算结果放出float[m]中,注意仍然按照object[m]中的顺序存放
    2. 划定边界
    a) 由于float[m]中各元素之和为1,所以在数轴上以元素的值为长度画出各个点如下图所示:
    0        点1       点2       点3………………………….  1  长度为    长度为
    float[0]      float[1]          依次类推b) 那么显然权值最小的所占的长度最短,权值最大的所占长度最长。然后取随机数x
    由于x在0~1之间是均匀分布的,所以相应的在长度长的地方(即权值大的地方)x出现的机率要大,这样就完成了。
    c) x落在哪个长度范围之内,就读这个长度对应权值的对象。
    d) 解毕
    但是怎么样控制误差范围我还没有想到方法
      

  3.   

    import java.util.*;public class Cryptogram {
    private Element[] spe;
    private static final char[] all;
    static{
    all = new char[126-33+1];
    for(int i=33; i<=126; i++){
    all[i-33] = (char) i;
    }
    }
    private char[] cry;
    private int length;

    /**
     * constructor
     * @param e the letter(s) withe specified probability
     * @param len the length of crytogram
     */
    public Cryptogram(Element[] e,int len){
    spe = new Element[e.length];
    System.arraycopy(e,0,spe,0,e.length);
    length = len;
    cry = new char[length];
    Arrays.fill(cry,(char)0);
    }


    /**
     * constructor
     * @param len length of crytogram
     */
    public Cryptogram(int len){
    spe = null;
    length = len;
    cry = new char[length];
    Arrays.fill(cry,(char)0);
    }


    /**
     * get the cryptogram
     * @return cryptogram
     */
    public String getCry(){
    if(spe!=null && spe.length!=0){
    for(int i=0; i<spe.length; i++){
    int min = (int)(spe[i].getMinPro() * length);
    int max = (int)(spe[i].getMaxPro() * length);
    int need = new Random().nextInt(max-min) + min;
    while(need>0){
    int tmp = new Random().nextInt(length);
    if(cry[tmp] != (char)0)
    continue;
    else{
    cry[tmp] = spe[i].getC();
    need--;
    }
    }
    }
    }

    Random rnd = new Random();
    for(int i=0; i<length; i++){
    if(cry[i] == (char)0){
    char c = all[rnd.nextInt(126-33)];
    for(int j=0; j<spe.length; j++){
    if(c==spe[j].getC()){
    c = all[rnd.nextInt(126-33)];
    j=0;
    }
    }
    cry[i] = c;
    }
    }

    return new String(cry);
    }


    public static void main(String args[]){
    Element[] e = new Element[]{new Element('a',0.08,0.05)};
    Cryptogram c = new Cryptogram(e,100);
    String s = c.getCry();
    System.out.println(s);

    /*test*/
    /*for(int i=0; i<s.length(); i++){
    if(s.charAt(i)=='a')
    System.out.print('a');
    }*/
    }
    }
    //----------------------------------------
    class Element{
    private char c;
    private double probability;
    private double error;

    public Element(char ch, double p,double e){
    c = ch;
    probability = p;
    error = e;
    }

    public char getC(){
    return c;
    }

    public double getMinPro(){
    return (probability - error);
    }

    public double getMaxPro(){
    return (probability + error);
    }

    }
      

  4.   

    稍微修改一下
    ------------------------
    import java.util.*;public class Cryptogram {
    private Element[] spe;
    private static final char[] all;
    static{
    all = new char[126-33+1];
    for(int i=33; i<=126; i++){
    all[i-33] = (char) i;
    }
    }
    private char[] cry;
    private int length;

    /**
     * constructor
     * @param e the letter(s) withe specified probability
     * @param len the length of crytogram
     */
    public Cryptogram(Element[] e,int len){
    spe = new Element[e.length];
    System.arraycopy(e,0,spe,0,e.length);
    length = len;
    cry = new char[length];
    Arrays.fill(cry,(char)0);
    }


    /**
     * constructor
     * @param len length of crytogram
     */
    public Cryptogram(int len){
    spe = null;
    length = len;
    cry = new char[length];
    Arrays.fill(cry,(char)0);
    }


    /**
     * get the cryptogram
     * @return cryptogram
     */
    public String getCry(){
    if(spe!=null && spe.length!=0){
    for(int i=0; i<spe.length; i++){
    int min = (int)(spe[i].getMinPro() * length);
    int max = (int)(spe[i].getMaxPro() * length);
    int need = new Random().nextInt(max-min) + min;
    while(need>0){
    int tmp = new Random().nextInt(length);
    if(cry[tmp] != (char)0)
    continue;
    else{
    cry[tmp] = spe[i].getC();
    need--;
    }
    }
    }
    }

    Random rnd = new Random();
    for(int i=0; i<length; i++){
    if(cry[i] == (char)0){
    char c = all[rnd.nextInt(126-33)];
    for(int j=0; spe!=null && j<spe.length; j++){//修改处
    if(c==spe[j].getC()){
    c = all[rnd.nextInt(126-33)];
    j=0;
    }
    }
    cry[i] = c;
    }
    }

    return new String(cry);
    }


    public static void main(String args[]){
    Element[] e = new Element[]{new Element('a',0.08,0.05)};
    Cryptogram c = new Cryptogram(e,50);
    String s = c.getCry();
    System.out.println(s);
    System.out.println(new Cryptogram(50).getCry());

    /*test*/
    /*for(int i=0; i<s.length(); i++){
    if(s.charAt(i)=='a')
    System.out.print('a');
    }*/
    }
    }
    //----------------------------------------
    class Element{
    private char c;
    private double probability;
    private double error;

    public Element(char ch, double p,double e){
    c = ch;
    probability = p;
    error = e;
    }

    public char getC(){
    return c;
    }

    public double getMinPro(){
    return (probability - error);
    }

    public double getMaxPro(){
    return (probability + error);
    }

    }
      

  5.   

    这个应该很简单的,取定一个char数组,其中只包含大小写字母和数字62个字符,a的个数最多,占到80%,然后随机在数组中取值,生成一个文件就行了
      

  6.   

    To troyzhang:
    a) 由于float[m]中各元素之和为1,所以在数轴上以元素的值为长度画出各个点如下图所示:
    0 点1 点2 点3…………………………. 1长度为 长度为
    float[0] float[1] 依次类推b) 那么显然权值最小的所占的长度最短,权值最大的所占长度最长。然后取随机数x
    由于x在0~1之间是均匀分布的,所以相应的在长度长的地方(即权值大的地方)x出现的机率要大,这样就完成了。
    大虾的意思是不是:
    根据probability的大小排序
    然后分别为:
    float[0],float[1].......float[i]
    之后取一个随机数x,范围为0~i 呢?
      

  7.   

    public class bbb {   public static void main(String[] args) {
        String bzstr = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
        StringBuffer pwd = new StringBuffer();
        int pwdlength = 100;
        int acount = 0;
        for (int i = 0; i < pwdlength; i++) {
        char c = bzstr.charAt((int) Math.floor(Math.random()
        * bzstr.length()));
        pwd.append(c);
        if (c == 'a')
        acount++;
        }
        System.out.println("生成的密码是" + pwd.toString() + "  \n 字母'a'的个数是"
        + acount + "   \n所占比例是" + acount * 100.0 / (double) pwdlength
        + "%");
       }
    }
      

  8.   

    原来你要准确等于80%,那用下面的方法
    public class bbb { public static void main(String[] args) {
      f();
     }
     
     static void f() {
      String bzstr = "AbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789";
      char ret[] = new char[100];
      for (int i = 0; i < 100; i++) {
      ret[i] = 'a';
      }
      Vector v = new Vector();
      for (int i = 0; i < 100; i++) {
      v.add(new Integer(i));
      }
      Vector rest = new Vector();
      for (int i = 0; i < 20; i++) {
      int index = (int) Math.floor(Math.random() * v.size());
      rest.addElement(v.get(index));
      v.remove(index);
      }
      for (int j = 0; j < rest.size(); j++) {
      ret[((Integer) rest.get(j)).intValue()] = bzstr.charAt((int) Math
      .floor(Math.random() * 61));
      }
      System.out.println(new String(ret));
     }
    }