根据字符类型和密码长度随机生成密码

原因

初衷:我本来是想写根据自己定义的一些信息生成复杂度可自选的固定密码,增强密码的复杂性的同时,也更容易记住密码,这样密码即使明文记录在本地,没有自己的加密算法,也得不到最终真正的密码。我看到网上有一些现成的工具以及chrome的插件等,还是想自己试试。

不过看到一些自动生成随机密码的网站,一好奇就先有了这篇随机生成密码的文章。

目标

可以选择数字,小写字母,大写字母,特殊符号,密码长度,根据这些选择生成随机的密码。

思路

思路1: 我的思路其实很简单粗暴,密码组成可以有数字,小写字母,大写字母,特殊符号4种选择,所以可以选择其中的1种,2种,3种,4种组成密码,分别对应的组合方式有4种,6种,4种,1种,其实就是简单的排列组合。然后根据选择了几种字符种类,就生成和为密码长度的几个随机数,然后到相应的字符种类中随机选择几个字符,把他们拼接在一起,最后打乱组成新密码。

例如:选择数字和小写字母组成长度为 10 的随机密码,程序会生成和为 10 的两个随机数,假设两个随机数是 4 和 6,则会从 0-9 十个数字和 a-z 26小写字母中中随机的选择 4 个数字和 6 个字母,然后把他们拼接在一起,最后打乱顺序就得到最终的随机密码。

我的想法很简单,如果有更好的方法,求告知,谢谢!

思路2: 另一种生成随机密码的方法,先拼装所有可能组成密码的字符类型,然后随机选择指定长度的n个字符,然后拿着这n字符校验是否包含选择了的字符类型的字符和是否不包含没有选择的字符类型的字符,这样不断重试,直到找到符合选择的字符类型字符串为止。这种方法可能重试的次数比较多,实现参考: https://github.com/lynchnf/password

思路1代码实现

package fun;

import java.util.*;

/**
 * Created by gary on 16/10/15.
 */
public class GeneratePassword {

    private static String number = "0123456789";
    private static String lowerChar = "abcdefghijklmnopqrstuvwxyz";
    private static String upperChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static String specialChar = "*$%!:;.,?&(-_)=#{[@]}";

    /**
     * 四种字符十五种组合方式随机产生密码
     * @param isNum
     * @param isLowerChar
     * @param isUpperChar
     * @param isSpecialChar
     * @param length
     * @return
     */
    private static String generPassword(boolean isNum, boolean isLowerChar, boolean isUpperChar, boolean isSpecialChar,
            int length) {
        String password = null;
        // 只选一种
        if (isNum && !(isLowerChar || isUpperChar || isSpecialChar))
            return genPwByNum(1, length, number);
        if (isLowerChar && !(isNum || isUpperChar || isSpecialChar))
            return genPwByNum(1, length, lowerChar);
        if (isUpperChar && !(isLowerChar || isNum || isSpecialChar))
            return genPwByNum(1, length, upperChar);
        if (isSpecialChar && !(isLowerChar || isUpperChar || isNum))
            return genPwByNum(1, length, specialChar);

        // 选择了两种
        if ((isNum && isLowerChar) && !(isUpperChar || isSpecialChar))
            return genPwByNum(2, length, number, lowerChar);
        if ((isNum && isUpperChar) && !(isLowerChar || isSpecialChar))
            return genPwByNum(2, length, number, upperChar);
        if ((isNum && isSpecialChar) && !(isLowerChar || isUpperChar))
            return genPwByNum(2, length, number, specialChar);
        if ((isLowerChar && isUpperChar) && !(isNum || isSpecialChar))
            return genPwByNum(2, length, lowerChar, upperChar);
        if ((isLowerChar && isSpecialChar) && !(isNum || isUpperChar))
            return genPwByNum(2, length, lowerChar, specialChar);
        if ((isUpperChar && isSpecialChar) && !(isNum || isLowerChar))
            return genPwByNum(2, length, upperChar, specialChar);

        // 选择了三种
        if ((isNum && isLowerChar && isUpperChar) && !isSpecialChar)
            return genPwByNum(3, length, number, lowerChar, upperChar);
        if ((isNum && isLowerChar && isSpecialChar) && !isUpperChar)
            return genPwByNum(3, length, number, lowerChar, specialChar);
        if ((isNum && isUpperChar && isSpecialChar) && !isLowerChar)
            return genPwByNum(3, length, number, upperChar, specialChar);
        if ((isLowerChar && isUpperChar && isSpecialChar) && !isNum)
            return genPwByNum(3, length, lowerChar, upperChar, specialChar);

        // 四种都选
        if (isNum && isLowerChar && isUpperChar && isSpecialChar)
            return genPwByNum(4, length, number, lowerChar, upperChar, specialChar);

        return password;

    }

    /**
     * 根据选择的字符类型生成密码
     * @param num
     * @param length
     * @param keys
     * @return
     */
    public static String genPwByNum(int num, int length, String... keys) {
        StringBuilder stringBuilder = new StringBuilder();
        if (length < num) {
            return stringBuilder.append("length should be bigger than ").append(num - 1).toString();
        }
        int[] randArray = randArr(num, length);
        int i = 0;
        for (String str : keys)
            stringBuilder.append(collectStr(randArray[i++], str));

        return shuffleString(stringBuilder.toString());
    }

    /**
     * 产生和为length的num个随机数
     * @param num
     * @param length
     * @return
     */
    public static int[] randArr(int num, int length) {
        Random random = new Random();
        int[] randArray = new int[num];
        int i = 0;
        if (num == 1) {
            randArray[i] = length;
        } else {
            while (num > 1) {
                int rand = random.nextInt(length - num + 1) + 1;
                randArray[i++] = rand;
                length -= rand;
                num--;
                if (num == 1) {
                    randArray[i] = length;
                }
            }
        }

        for (int m : randArray) {
            System.out.println(m);
        }

        return randArray;
    }

    /**
     * 随机拼装字符
     * @param length
     * @param sample
     * @return
     */
    public static String collectStr(int length, String sample) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < length; i++) {
            stringBuilder.append(sample.charAt((int) (Math.random() * sample.length())));
        }
        return stringBuilder.toString();
    }

    /**
     * 打乱字符串
     * @param str
     * @return
     */
    public static String shuffleString(String str) {
        StringBuilder stringBuilder = new StringBuilder();
        List list = Arrays.asList(str.split(""));
        Collections.shuffle(list);
        for (String s : list) {
            stringBuilder.append(s);
        }
        return stringBuilder.toString();
    }

    public static void main(String[] args) {
        String password = generPassword(true, true, true, true, 10);
        System.out.println(password);
        // randArr(4, 10);

    }
}

你可能感兴趣的:(Fun,chrome,密码,算法,随机,字符)