根据身份证号判断证件持有人的性别、年龄、生日。废话不多说,直接上代码。
public class IdentifyCard { private static final Integer[] ODD_NUMS = {1, 3, 5, 7, 9}; private static final Integer[] EVEN_NUMS = {0, 2, 4, 6, 8}; private static final ThreadLocal<SimpleDateFormat> DATE_FORMAT_THREAD_LOCAL = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyyMMdd")); /** * @param area 地区码,如:110101 * @param birthday 出生日期:20000101 * @param sex 性别:0=男;1=女 * @param size 最小1;最大500 * @return results 生成结果集 */ public static String[] generator(String area, Date birthday, int sex, int size) { SexEnum.checkSex(sex); checkSize(size); List<String> resultList = new ArrayList<>(size); String simpleBirthday = DATE_FORMAT_THREAD_LOCAL.get().format(birthday); Set<String> numbers = ordinalNumbers(sex, size); for (String seqNo : numbers) { String prefix = area + simpleBirthday + seqNo; String cardNo = prefix + getCheckCode(prefix); resultList.add(cardNo); } String[] results = resultList.toArray(new String[size]); new RandomSort<String>(results).changePosition(); return results; } private static void checkSize(int size) { if (size < 1 || size > 500) { throw new IllegalArgumentException("The size min 1, max 500."); } } // prefix = area + birthdayFormat + seqNo private static String getCheckCode(String prefix) { int sum = 0; for (int i = 0; i < prefix.length(); i++) { DigitsEnum digitsEnum = DigitsEnum.get(i + 1); int seatVal = Integer.parseInt(prefix.substring(i, i + 1)); sum = sum + seatVal * digitsEnum.getValue(); } return CheckCode.get(sum); } // generated ordinal numbers by sex and size. private static Set<String> ordinalNumbers(int sex, int size) { Set<String> results = new HashSet<>(); String[] sequenceArrays = sequenceArrays(); Integer[] nums = SexEnum.getNums(sex); new RandomSort<Integer>(nums).changePosition(); int count = 0; for (String sequence : sequenceArrays) { for (int sexNum : nums) { results.add(sequence + sexNum); count ++; if (count == size) { break; } } if (count == size) { break; } } return results; } // generated disorder sequence arrays. public static String[] sequenceArrays() { Set<String> resultSet = new HashSet<>(); String[] numbers = sequenceNumbers(); new RandomSort<String>(numbers).changePosition(); for (String first : numbers) { for (String second : numbers) { resultSet.add(first + second); } } String[] array = resultSet.toArray(new String[]{}); new RandomSort<String>(array).changePosition(); return array; } // generated orderly sequence numbers. private static String[] sequenceNumbers() { String[] numbers = new String[10]; for (int i = 0; i <= 9; i++) { numbers[i] = Integer.toString(i); } return numbers; } /** * sex enum */ private enum SexEnum { male(0, ODD_NUMS, "male"), female(1, EVEN_NUMS, "female"); private int code; private Integer[] nums; private String desc; public static void checkSex(int sex) { for (SexEnum sexEnum : SexEnum.values()) { if (sexEnum.getCode() == sex) { return; } } throw new IllegalArgumentException("The sex 0:male 1:female."); } public static Integer[] getNums(int code) { for (SexEnum sexEnum : SexEnum.values()) { if (sexEnum.getCode() == code) { return sexEnum.getNums(); } } throw new IllegalArgumentException("Sex code not match."); } SexEnum(int code, Integer[] nums, String desc) { this.code = code; this.nums = nums; this.desc = desc; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public Integer[] getNums() { return nums; } public void setNums(Integer[] nums) { this.nums = nums; } public String getDesc() { return desc; } public void setDesc(String desc) { this.desc = desc; } } /** * check code */ private enum CheckCode { zero(0, "1"), one(1, "0"), two(2, "X"), three(3, "9"), four(4, "8"), five(5, "7"), six(6, "6"), seven(7, "5"), eight(8, "4"), nine(9, "3"), ten(10, "2"), ; /* remainder */ private int remainder; private String code; public static String get(int sum) { int remainder = sum % 11; for (CheckCode checkCode : CheckCode.values()) { if (checkCode.getRemainder() == remainder) { return checkCode.getCode(); } } throw new IllegalArgumentException("not found."); } CheckCode(int remainder, String code) { this.remainder = remainder; this.code = code; } public int getRemainder() { return remainder; } public void setRemainder(int remainder) { this.remainder = remainder; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } } /** * digits factor */ private enum DigitsEnum { one(1, 7), two(2, 9), three(3, 10), four(4, 5), five(5, 8), six(6, 4), seven(7, 2), eight(8, 1), nine(9, 6), ten(10, 3), eleven(11, 7), twelve(12, 9), thirteen(13, 10), fourteen(14, 5), fifteen(15, 8), sixteen(16, 4), seventeen(17, 2), eighteen(18, -1); /* What's the number one. */ private int seat; private int value; DigitsEnum(int seat, int value) { this.seat = seat; this.value = value; } public static DigitsEnum get(int seat) { if (seat < 0 || seat > 17) { throw new IllegalArgumentException("The seat value min 1, max 17."); } for (DigitsEnum digitsEnum : DigitsEnum.values()) { if (digitsEnum.getSeat() == seat) { return digitsEnum; } } throw new IllegalArgumentException("not found."); } public int getSeat() { return seat; } public void setSeat(int seat) { this.seat = seat; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } } private static class RandomSort<T> { private final Random random = new Random(); private final T[] positions; private final int SIZE; public RandomSort(T[] positions) { this.positions = positions; this.SIZE = positions.length; } public void changePosition() { for (int index = SIZE - 1; index >= 0; index--) { exchange(random.nextInt(index + 1), index); } } private void exchange(int p1, int p2) { T temp = positions[p1]; positions[p1] = positions[p2]; positions[p2] = temp; } } }