模拟姓名、IdentityCard、年龄、性别信息生成工具

博主声明:

转载请在开头附加本文链接及作者信息,并标记为转载。本文由博主 威威喵 原创,请多支持与指教。

本文首发于此   博主:威威喵  |  博客主页: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、身份证号码生成工具类,数据虽然是模拟的,但都是模拟现实的身份证号码,按照身份证号码的规定来生成的。

数据格式:

  • 1~6 位数字:表示区号,1~2是省份代码,2~4是市区、县级代码。
  • 7~14 位数字:表示出生年月,按照给定的年份和岁数范围进行生成。比如今年2019年,90岁范围,就会用2019减去90的范围内随机生成出生年月信息。
  • 15~17 位数字:表示序号,这个比较随意。
  • 第 17 位数字:表示性别的判定,男单数、女双数。
  • 第 18 位数字:表示校验码,有 0~9 和 X 字符,其中 X 表示数字 10
  • 月份还分大小月、闰年的情况,都做了处理

     数据格式介绍完毕,然后是性别和年龄,这个不是随机的,根据身份证号码进行计算和判定得来的,比如你输入的是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--;
		}
		
	}
}

生成的数据格式展示:

 最后,发一句牢骚话,这个姓氏和名字我搞了好久,太耗时间了。能不能点个赞就靠你了。

你可能感兴趣的:(数据库基础)