博主声明:
转载请在开头附加本文链接及作者信息,并标记为转载。本文由博主 威威喵 原创,请多支持与指教。
本文首发于此 博主:威威喵 | 博客主页:https://blog.csdn.net/smile_running
之前在写数据库信息的时候,要去测试数据库的性能,由于数据库里面并没有数据信息,所以写了一个模拟的数据库信息生成的工具类,有身份证、姓名、年龄等字段信息。身份证是随机生成的,但并不是胡乱随机的数字,都是按我们的省份代码,出生年月、以及尾部号码等做了细节的处理。生成的身份证号码不会重复,我用了一个 Set 集合保证数据的单一性。
简单介绍一下这个工具的数据格式。
1、姓名信息:包含 2~4 字不等,姓氏很多,包括复姓,姓名随机组合,有单字和双字。代码如下:
package com.xww;
import java.time.Clock;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* 随机姓名生成器
*
* @author xww
* @博客 https://blog.csdn.net/smile_running?t=1
*/
public class RandomNameMaker {
public static List getFullNameList(int count) {
final long start = Clock.systemDefaultZone().millis();
final List fullNameList = new ArrayList();
final List surnameList = getSurnameSet(count);
final List nameList = getNameSet(count);
// 进行 姓氏与名字 拼接
for (int i = 0; i < count; i++) {
fullNameList.add(surnameList.get(i) + nameList.get(i));
}
final long end = Clock.systemDefaultZone().millis();
System.out.println("生成姓名:" + fullNameList.size() + "个\n" + "耗时:"
+ (end - start) + "ms");
return fullNameList;
}
/**
* 姓氏可以重复 ,1~2字(单姓、复姓)
*
* @param 条目
* @return 姓氏集合
*/
private static List getSurnameSet(int count) {
Random r = new Random();
List surnameList = new ArrayList(count);
// 随机读取数组,生成姓氏
final String surname[] = { "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "林",
"傅", "许", "宋", "江", "洪", "游", "包", "钟", "陈", "菜", "曹", "高",
"杨", "甘", "黄", "兰", "雷", "梁", "张", "章", "刘", "吕", "欧", "裘",
"苏", "任", "温", "翁", "徐", "谢", "郭", "薛", "段", "楚", "叶", "赖",
"何", "沈", "卓", "施", "邱", "凌", "涂", "池", "龙", "曾", "熊", "戴",
"严", "汤", "汪", "侯", "卢", "蓝", "冯", "方", "颜", "石", "朱", "袁",
"邓", "丁", "庄", "康", "邹", "廖", "向", "郝", "杜", "易", "顾", "朱",
"花", "焦", "毛", "华", "田", "莫", "尤", "金", "尚", "谭", "隆", "曲",
"马", "盘", "武", "陆", "典", "艾", "董", "萧", "陶", "简", "安", "贝",
"白", "成", "崔", "霍", "常", "程", "荆", "邢", "展", "代", "狄", "韩",
"孔", "费", "申", "樊", "房", "付", "葛", "关", "谷", "龚", "胡", "古",
"房", "付", "盖", "宫", "后", "海", "贺", "牛", "罗", "蒋", "姜", "姬",
"井", "鞠", "贾", "景", "纪", "解", "靳", "甲", "柯", "柳", "黎", "娄",
"冷", "麦", "闫", "宁", "聂", "步", "南", "品", "彭", "平", "于", "浦",
"庞", "裴", "秦", "齐", "乔", "阮", "沙", "胜", "萨", "夏", "腾", "佟",
"唐", "巫", "伍", "万", "魏", "文", "史", "韦", "肖", "俞", "余", "玉",
"宇", "伊", "言", "左", "岳", "詹", "窦", "盘", "墨", "芈", "甄", "赢",
"廉", "詹", "南宫", "司马", "诸葛", "百里", "上官", "公孙", "东方", "欧阳", "独孤",
"皇甫", "司徒", "长孙", "慕容", "夏侯", "拓拔", "司空", "西门", "东郭", "端木",
"纳兰", "完颜", "宇文", "轩辕", "尉迟", "耶律", "令狐", "东皇", "呼延", "太史",
"司寇", "澹台", "单于", };
final int len = surname.length;
final int total = count;// 生成的名字数量
String newSurname = "";
int size = surnameList.size();
while (size < total) {
newSurname = surname[r.nextInt(len)];
surnameList.add(newSurname);
size = surnameList.size();
}
return surnameList;
}
/**
* 名字允许重复 1、名字长度:1~2字
*
* @do 一个随机数,判断0和1,名字在 1~2 字之间切换
* @param 条目
* @return 名字集合
*/
private static List getNameSet(int count) {
Random r = new Random();
List nameList = new ArrayList(count);
// 随机读取数组,生成名字
final String name[] = { "月", "节", "杰", "威", "为", "里", "橙", "岑", "参",
"点", "时", "未", "美", "霖", "琳", "临", "灵", "令", "玲", "久", "九",
"娘", "歌", "哥", "全", "明", "日", "国", "果", "项", "相", "勤", "青",
"清", "能", "雄", "天", "答", "梅", "开", "卡", "合", "和", "舍", "男",
"军", "骏", "君", "隽", "恩", "额", "油", "佑", "码", "帕", "新", "抢",
"达", "竣", "名", "茗", "鸣", "命", "民", "敏", "珉", "蜜", "米", "秘",
"觅", "组", "祖", "卒", "式", "师", "实", "示", "适", "意", "宜", "魂",
"环", "欢", "幻", "田", "待", "松", "嵩", "微", "维", "伟", "薇", "玮",
"问", "斌", "宾", "滨", "兵", "彬", "冰", "屏", "丙", "栟", "页", "野",
"夜", "邪", "冶", "烨", "置", "知", "字", "志", "智", "直", "支", "至",
"质", "芝", "治", "枝", "芷", "织", "挚", "若", "偌", "洛", "萝", "落",
"婷", "庭", "廷", "德", "匹", "平", "庆", "丕", "好", "冒", "猫", "茂",
"矛", "卯", "圈", "权", "泉", "铨", "域", "鱼", "考", "爱", "暧", "晴",
"箐", "情", "倾", "琴", "沁", "层", "熟", "叟", "奎", "葵", "愧", "桂",
"云", "韵", "运", "允", "芸", "匀", "蕴", "管", "官", "冠", "光", "量",
"亮", "连", "凉", "靓", "联", "莲", "恋", "帘", "信", "鑫", "欣", "芯",
"心", "馨", "歆", "锌", "形", "醒", "星", "兴", "幸", "杏", "骍", "香",
"乡", "享", "祥", "想", "翔", "巷", "湘", "芗", "养", "样", "羊", "空",
"木", "阳", "洋", "央", "杨", "拓", "司", "门", "东", "端", "纳", "雀",
"烟", "颜", "燕", "轩", "迟", "律", "令", "皇", "艳", "炎", "岩", "妍",
"雁", "台", "单", "宴", "焉", "焱", "嫣", "砚", "先", "现", "仙", "显",
"贤", "闲", "鲜", "弦", "献", "纤", "宪", "冼", "羡", "娴", "炀", "仰",
"漾", "藕", "耦", "末", "土", "兔", "荼", "棉", "绵", "免", "冕", "缅",
"店", "娜", "那", "陌", "默", "水", "岁", "随", "虽", "遂", "岛", "道",
"稻", "奥", "傲", "宝", "别", "币", "毕", "碧", "壁", "笔", "璧", "壳",
"客", "思", "丝", "斯", "寺", "巳", "丹", "旦", "郸", "当", "党", "员",
"源", "园", "圆", "缘", "苑", "鸢", "沅", "因", "音", "印", "银", "吟",
"寅", "茵", "荫", "垠", "胤", "依", "义", "翼", "乙", "仪", "怡", "亿",
"艺", "衣", "益", "异", "毅", "议", "轶", "祎", "凡", "帆", "蕃", "氾",
"法", "乏", "筏", "垡", "佱", "芳", "坊", "悔", "灰", "慧", "汇", "辉",
"惠", "卉", "晖", "茴", "荟", "讳", "珲", "动", "冬", "冻", "栋", "勾",
"媾", "匹", "又", "优", "邮", "友", "幽", "悠", "攸", "忧", "见", "劲",
"间", "建", "健", "剑", "坚", "鉴", "茧", "福", "副", "夫", "富", "复",
"弗", "女", "算", "将", "浆", "疆", "匠", "工", "公", "今", "尽", "禁",
"锦", "津", "晋", "晶", "静", "瑾", "京", "镜", "净", "菁", "婧", "睛",
"叉", "察", "岔", "总", "纵", "踪", "宗", "注", "忒", "泰", "体", "题",
"缇", "屉", "视", "透", "忑", "骨", "儿", "尔", "耳", "洱", "珥", "梦",
"萌", "词", "慈", "修", "休", "秀", "绣", "宿", "朽", "琇", "雕", "迪",
"其", "气", "器", "起", "期", "奇", "骑", "启", "琦", "琪", "棋", "柒",
"祺", "祁", "弃", "崎", "奕", "戚", "汽", "契", "泣", "旗", "岂", "离",
"俐", "丽", "礼", "莉", "力", "梨", "励", "厉", "荔", "吏", "璃", "笠",
"砾", "骊", "狸", "隶", "沥", "篱", "厘", "计", "机", "几", "记", "基",
"极", "积", "济", "忌", "际", "迹", "冀", "骥", "霁", "蓟", "玑", "素",
"酥", "涑", "数", "树", "叔", "熟", "书", "疏", "舒", "术", "姝", "淑",
"竖", "殊", "枢", "漱", "黍", "纾", "倏", "笑", "小", "校", "霄", "潇",
"骁", "宵", "孝", "逍", "啸", "占", "战", "盏", "崭", "赞", "簪", "昝",
"定", "鼎", "叮", "仔", "紫", "兹", "姿", "态", "真", "孜", "姊", "缁",
"第", "碌", "帝", "笛", "蒂", "谛", "玢", "户", "虎", "珑", "陇", "缎",
"路", "录", "露", "鹿", "芦", "泸", "舞", "学", "血", "雪", "仁", "壬",
"荏", "元", "苑", "蕴", "喜", "细", "熙", "夕", "昔", "兮", "曦", "行",
"茜", "谦", "朋", "湓", "蓬", "莱", "籁", "菊", "桔", "精", "册", "策",
"澈", "泽", "哲", "喆", "柘", "塔", "沓", };
final int len = name.length;
final int total = count;// 生成的名字数量
String newName = "";
int size = nameList.size();
while (size < total) {
newName = r.nextInt(2) > 0 ? name[r.nextInt(len)] : name[r
.nextInt(len)] + name[r.nextInt(len)];
nameList.add(newName);
size = nameList.size();
}
return nameList;
}
}
2、身份证号码生成工具类,数据虽然是模拟的,但都是模拟现实的身份证号码,按照身份证号码的规定来生成的。
数据格式:
数据格式介绍完毕,然后是性别和年龄,这个不是随机的,根据身份证号码进行计算和判定得来的,比如你输入的是2019年,就会减去她的出生日期,得到真实年龄。性别是根据身份证第 17 位数字判断是男还是女。
代码如下,身份证号码工具:
package com.xww;
import java.time.Clock;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
/**
* 随机的身份证号码生成工具
*
* @author xww
* @博客 https://blog.csdn.net/smile_running?t=1
*/
public class RandomIdCardMaker {
public static Set getFullIdCardList(int count) {
final long start = Clock.systemDefaultZone().millis();
// 身份证,使用不可重复集合
final Set idCardList = new HashSet();
final List number_1to6 = get_1_to_6_Number(count);
final List number_7to14 = get_7_to_14_Number(count, 2019, 90);
final List number_15to17 = get_15_to_17_Number(count);
final List number_18 = get_18_Number(count);
for (int i = 0; i < count; i++) {
idCardList.add(number_1to6.get(i) + number_7to14.get(i)
+ number_15to17.get(i) + number_18.get(i));
}
int realSize = idCardList.size();
int repetition = count - realSize;
final long end = Clock.systemDefaultZone().millis();
System.out.println("生成身份证号码:" + count + "条," + "重复:" + repetition
+ "条\n" + "去重复后,实际:" + realSize + "条\n" + "耗时:" + (end - start)
+ "ms");
return idCardList;
}
/**
* 获取身份证 1-6 位数字
*
* @return 可重复集合
*/
private static List get_1_to_6_Number(int count) {
Random r = new Random();
List nList_1to6 = new ArrayList(count);
String number_1_to_6 = "";
int size = nList_1to6.size();
final int total = count;
// 中国省份代号,非规律(真实代号),11 表示北京
final int n1to2[] = new int[] { 11, 12, 13, 14, 15, 21, 22, 23, 31, 32,
33, 34, 35, 36, 37, 41, 42, 43, 44, 45, 46, 50, 51, 52, 53, 54,
61, 62, 63, 64, 65, 71, 81, 82 };
int len = n1to2.length;
String s1to2 = "";
int n3to4 = 0;
String s3to4 = "";
int n5to6 = 0;
String s5to6 = "";
while (size < total) {
// 省级代号
s1to2 = String.valueOf(n1to2[r.nextInt(len)]);
// 城市代号 ,01 ~ 99 两位数
n3to4 = (r.nextInt(99)) + 1;
s3to4 = n3to4 < 10 ? "0" + String.valueOf(n3to4) : String
.valueOf(n3to4);
// 县级代号 ,01 ~ 99 两位数
n5to6 = (r.nextInt(99)) + 1;
s5to6 = n5to6 < 10 ? "0" + String.valueOf(n5to6) : String
.valueOf(n5to6);
number_1_to_6 = s1to2 + s3to4 + s5to6;// 拼接
nList_1to6.add(number_1_to_6);
size = nList_1to6.size();
}
return nList_1to6;
}
/**
* 生成随机的 出生日期
*
* @param year
* 当前或目标年份
* @param oldRange
* 年龄范围
* @return 可重复集合
*/
private static List get_7_to_14_Number(int count, int year,
int oldRange) {
Random r = new Random();
List nList_7to14 = new ArrayList(count);
final int total = count;
int size = nList_7to14.size();
String number_7_to_14 = "";
// 年份:合理设计,至今应该不超过 90 岁
int cYear = year;// 今年日期
int old = 0;
// 出生年份
int bornYear = 0;
String sYear = "";
// 出生月份
int month = 0;
String sMonth = "";
// 日期
int day = 0;
String sDay = "";
boolean isLeap = false;
while (size < total) {
// 年份
old = r.nextInt(oldRange) + 1;
bornYear = cYear - old;// 获得出生年份
sYear = String.valueOf(bornYear);
// 月份:1-12月,固定
month = r.nextInt(12) + 1;
sMonth = month < 10 ? "0" + String.valueOf(month) : String
.valueOf(month);
// 日期,大月31天,小月30天
if (month == 2) {// 如果是 2 月,判断是不是闰年,2月闰年有 29 天,平年 28 天,
isLeap = YearUtil.isLeapYear(bornYear);
if (isLeap) {
day = r.nextInt(29) + 1;
} else {
day = r.nextInt(28) + 1;
}
} else {
if (month % 2 == 0) {// 如果是 双月
day = r.nextInt(31) + 1;
} else {// 单月
day = r.nextInt(30) + 1;
}
}
sDay = day < 10 ? "0" + String.valueOf(day) : String.valueOf(day);
number_7_to_14 = sYear + sMonth + sDay;
nList_7to14.add(number_7_to_14);
size = nList_7to14.size();
}
return nList_7to14;
}
/**
* 获取 15~17 位数,其中第17位,单数代表男,双数代表女
*
* @return 可重复集合
*/
private static List get_15_to_17_Number(int count) {
Random r = new Random();
final int total = count;
List nList_15to17 = new ArrayList(count);
int size = nList_15to17.size();
int n15to17 = 0;
String s15to17 = "";
while (size < total) {
n15to17 = r.nextInt(999) + 1;
if (n15to17 < 10) {
s15to17 = String.valueOf("00" + n15to17);
} else if (n15to17 < 100) {
s15to17 = String.valueOf("0" + n15to17);
} else {
s15to17 = String.valueOf(n15to17);
}
nList_15to17.add(s15to17);
size = nList_15to17.size();
}
return nList_15to17;
}
/**
* 第18位代表校验码,X 表示数字 10
*
* @return 可重复集合
*/
private static List get_18_Number(int count) {
Random r = new Random();
final int total = count;
List nList_18 = new ArrayList(count);
int size = nList_18.size();
String s18 = "";
while (size < total) {
// (最后一位为 X,发生几率 < 1% )
s18 = r.nextInt(100) == 99 ? "X" : String.valueOf(r.nextInt(10));
nList_18.add(s18);
size = nList_18.size();
}
return nList_18;
}
}
下面是年龄、性别的判断工具:
package com.xww;
public class YearUtil {
/**
* 判断是否是闰年
*
* @param year
* @return 是闰年
*/
public static boolean isLeapYear(int year) {
boolean isLeap = false;
if (year % 4 == 0 || year % 100 == 0 || year % 400 == 0) {
isLeap = true;
}
return isLeap;
}
/**
* 通过计算差值,获取年龄
*
* @param year
* 今年
* @param identityCard
* 身份证号码
* @return 年龄
*/
public static int getAge(int year, String identityCard) {
int age = 0;
if (identityCard != null && identityCard.length() == 18) {
age = year - Integer.valueOf(identityCard.substring(6, 10));
}
return age;
}
/**
* 根据身份证第 17 位,判断男(单),女(双)
*
* @param identityCard
* @return
*/
public static String getGender(String identityCard) {
if (identityCard != null && identityCard.length() == 18) {
return Integer.valueOf(identityCard.charAt(16)) % 2 == 0 ? "女"
: "男";
}
return null;
}
}
最后是客户端代码,运行就可以生成数据了。
package com.xww;
import java.util.Iterator;
import java.util.List;
/**
*
* @author xww
*
*/
public class Main {
public static void main(String[] args) {
int count = 10000;
final List names = RandomNameMaker.getFullNameList(count);
Iterator iterator = RandomIdCardMaker.getFullIdCardList(count)
.iterator();
int size = names.size() - 1;
String identityCard = "";
while (iterator.hasNext()) {
identityCard = iterator.next();
System.out.println("身份证:" + identityCard + " - 姓名:"
+ names.get(size) + " - 性别:"
+ YearUtil.getGender(identityCard) + " - 年龄:"
+ YearUtil.getAge(2019, identityCard));
size--;
}
}
}
生成的数据格式展示:
最后,发一句牢骚话,这个姓氏和名字我搞了好久,太耗时间了。能不能点个赞就靠你了。