package com.lzh.util; import java.util.Date; import java.util.Random; /** * 字符串处理工具类 * * @author luozehua * @date 2014年3月20日 * @time 下午4:24:18 */ public class StringUtil { /** * 加权因子 */ private final static int[] DIVISOR = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 }; /** * 校验码 */ private final static char[] VALIDATECODE = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' }; /** * 验证码字符表 */ private final static char[] CHECKNO = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y' }; /** * 检查一个字符串是否为空(null、“”或全部为空格) * * @param checkString * @return */ public static boolean isEmpty(final String checkString) { return checkString == null || checkString.trim().length() == 0; } /** * 检查一个字符串是否为数字(包含小数) * * @param checkString * @return */ public static boolean isDigit(final String checkString) { return checkString.matches("^\\d+$") || checkString.matches("^\\d+(\\.\\d+)*$"); } /** * 解析一个文件名字符串,取文件的扩展名 * * @param fileName * 文件名 * @return 文件名后缀 */ public static String getFileSuffix(final String fileName) { if (isEmpty(fileName)) { return "-1"; } else if (fileName.indexOf(".") == 0) { return "-1"; } if (fileName.split("\\.").length == 1) { // 没有后缀名 return null; } return fileName.substring(fileName.lastIndexOf(".") + 1); } /** * 解析一个文件名字符串,取不含扩展名的文件名 * * @param fileName * 文件名 * @return 去除后缀后的文件名 */ public static String getStringExceptFileSuffix(final String fileName) { if (isEmpty(fileName)) { return "-1"; } else if (fileName.indexOf(".") == 0) { return "-1"; } if (fileName.split("\\.").length == 1) { // 没有后缀名 return fileName.substring(0, fileName.length() - 1); } return fileName.substring(0, fileName.lastIndexOf(".")); } /** * 生成一个指定位数的验证码,规则如下: * 验证码每一位可取:数字0~9,小写字母a、b、c、d、e、f、g、h、i、j、k、m、n、p、q、r、s、t、u、v、w、x、y * 验证码每一位随机取以上字符 * * @param number * 验证码的位数 * @return */ public static String getCheckNum(final int number) { if (number == 0) { return "0位验证码"; } String checkString = ""; // 产生0~32之间的随机数 Random random = new Random(); for (int i = 0; i < number; i++) { int num = random.nextInt(CHECKNO.length); checkString += CHECKNO[num]; } return checkString; } /** * 根据指定的ID(数字字符串)生成一个指定长度的新ID,规则如下: * ■ 如果指定的ID为空,生成的ID全部为“0” * ■如果指定的ID不为空,生成的ID值取指定ID的值再加1 * ■ 如果生成的ID不够指定的长度,则左补“0” * @param oldId * 原有的ID * @param length * 新生成ID的长度 * @return */ public static String getNewIdByOldId(final String oldId, final Integer length) { StringBuffer buffer = new StringBuffer(); // 指定的ID为空,生成的ID全部为“0” if (StringUtil.isEmpty(oldId)) { return String.format("%0" + length + "d", 0); } // 指定的ID不是数字字符串 if (!StringUtil.isDigit(oldId)) { return "-1"; } // 原字符长度 int oldIdLength = oldId.length(); int index = 0; // 指定输出长度小于原有ID长度 if (oldIdLength > length) { return "-1"; } // 找到最后一个不是为9的位置 for (int i = oldIdLength - 1; i >= 0; i--) { if (oldId.charAt(i) != '9') { index = i; break; } } if (index == 0) { // 全部字符都为9 int first = Integer.parseInt(oldId.charAt(0) + ""); if (first == 9) { buffer.append(1).append(String.format("%0" + oldIdLength + "d", 0)); } else { buffer.append(first + 1).append(oldId.substring(1)); } return getNewId(length, buffer); } else if (index == oldIdLength - 1) { // 最后位置没有出现9 buffer.append(oldId.substring(0, oldIdLength - 1)).append((char) ((int) oldId.charAt(oldIdLength - 1) + 1)); return getNewId(length, buffer); } else { buffer.append(oldId.substring(0, index)).append((char) ((int) oldId.charAt(index) + 1)) .append(String.format("%0" + (oldId.length() - index - 1) + "d", 0)); return getNewId(length, buffer); } } private static String getNewId(final Integer length, StringBuffer newBuffer) { if (newBuffer.length() > length) { return "-1"; } else if (newBuffer.length() == length) { return newBuffer.toString(); } else { return String.format("%0" + (length - newBuffer.length()) + "d", 0).concat(newBuffer.toString()); } } /** * 检查一个字符串是否符合手机号格式。格式为: * ■ 长度11位 * ■ 每一位必须为数字 * * @param phoneNum * 要验证的手机号码 * @return */ public static boolean isMobile(final String phoneNum) { return phoneNum.matches("^1[34589]\\d{9}$"); } /** * 检查一个字符串是否符合电话号码格式。格式为: * ■ 每一位只允许数字或连接符“-” * ■ “-”两边不得为空 * @param phoneNum * @return */ public static boolean isPhone(final String phoneNum) { return phoneNum.matches("^(\\d{3,4}-)\\d{7,8}$"); } /** * 检查一个字符串是否符合Email格式。格式为: 必须包函且只能包函一个符号“@” “@”两边不得为空 * * @param email * 要验证的邮箱地址 * @return */ public static boolean isEmail(final String email) { return email.matches("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$"); } /** * 检查一个字符串是否符合旧身份证号格式。格式为: * ■ 长度15位 * ■ 每一位必须为数字 * ■ 出生日期必须为一个合法日期(年、月、日必须合法) * ■出生日期在(19)00年1月1日至(19)99年12月31日之间 * ■ 旧身份证号编码规则: * 1.第1至6位为身份证编码对象的所在地(出生地)的编码 * 2.第7至12位为出生年、月、日(YYMMDD,不包含世纪) * 3.第13至15位为顺序号。男性为奇数,女性为偶数 * * @param oldIdCard * 旧的身份证 * @return */ public static boolean isOldIdCard(final String oldIdCard) { if (!oldIdCard.matches("^\\d{15}$")) { return false; } String birthday = oldIdCard.substring(6, 12); if (!DateTimeUtil.isDateStr(birthday, "yyMMdd")) { return false; } return true; } /** * 检查一个字符串是否符合新身份证号格式。格式为: * • 长度18位 • 前17位必须为数字;第18位可以是数字、“X”或“x” * • 出生日期必须为一个合法日期(年、月、日必须合法) * • 出生日期在1900年1月1日至当前日期之前 * • 校验位合法 * • 新身份证号编码规则 * 1.第1至6位为身份证编码对象的所在地(出生地)的编码 * 2. 第7至14位为出生年、月、日(YYYYMMDD) * 3.第15至17位为顺序号。男性为奇数,女性为偶数 * 4. 第18位为校验位,计算规则为: * A.前17位的数字不其对应的加权因子:7、9、10、5、8、4、2、1、6、3、7、9、10、5、8、4、2相乘 * B . 再将积相加 * C.最后的和再除以11,取其余 D. 根据余数0到10,取对应的校验码:1、0、X、9、8、7、6、5、4、3、2 * @param newIdCard * 二代身份证 * @return */ public static boolean isNewIdCard(final String newIdCard) { if (!newIdCard.matches("^\\d{17}(\\d|x|X)$")) { return false; } String birthday = newIdCard.substring(6, 14); if (!DateTimeUtil.isDateStr(birthday, "yyyyMMdd")) { return false; } if (DateTimeUtil.parseStringToDate(birthday, "yyyyMMdd").after(new Date())) { return false; } // 检验最后以为 if (!checkLastLetter(newIdCard)) { return false; } return true; } /** * 检验新身份证最后一个校验位的合法性 * @param newIdCard * @return */ private static boolean checkLastLetter(final String newIdCard) { String str = newIdCard.substring(0, 17); String last = newIdCard.substring(17); // 加权因子校验 char[] numChar = str.toCharArray(); Long result = 0L; for (int i = 0; i < numChar.length; i++) { result += Integer.parseInt(Character.toString(numChar[i])) * DIVISOR[i]; } int checkIndex = (int) (result % 11); if (Character.toString(last.toCharArray()[0]).equalsIgnoreCase(Character.toString(VALIDATECODE[checkIndex]))) { return true; } return false; } /** * 将一个旧身份证号升级为一个新身份证号(世纪取19) * * @param oldIdCard * @return */ public static String changeOldIdCardToNewIdCard(final String oldIdCard) { if (!StringUtil.isOldIdCard(oldIdCard)) { return "-1"; } // 获取旧身份证的前六位 String locationStr = oldIdCard.substring(0, 6); String idStr = oldIdCard.substring(6); String newId = locationStr.concat("19").concat(idStr); // 计算出校验因子 char[] numChar = newId.toCharArray(); Long result = 0L; for (int i = 0; i < numChar.length; i++) { result += Integer.parseInt(Character.toString(numChar[i])) * DIVISOR[i]; } int checkIndex = (int) (result % 11); String lastStr = Character.toString(VALIDATECODE[checkIndex]); return newId.concat(lastStr); } }