java身份证合法性校验工具类实例代码

2025-05-29 0 35

1.身份证规则

计算方法(来源百度)

  1. 将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
  2. 将这17位数字和系数相乘的结果相加。
  3. 用加出来和除以11,看余数是多少?
  4. 余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X -9-8-7-6-5-4-3-2。(即余数0对应1,余数1对应0,余数2对应X…)
  5. 通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是2,身份证的最后一位号码就是罗马数字x。

例如: 某男性的身份证号码为【53010219200508011x】, 我们看看这个身份证是不是合法的身份证

首先我们得出前17位的乘积和【(57)+(39)+(010)+(15)+(08)+(24)+(12)+(91)+(26)+(03)+(07)+(59)+(010)+(85)+(08)+(14)+(1*2)】是189,然后用189除以11得出的结果是189/11=17—-2,也就是说其余数是2。最后通过对应规则就可以知道余数2对应的检验码是X。所以,可以判定这是一个正确的身份证号码。

2. 代码逻辑

本工具类提供了3种类型校验

  1. 18位身份证号码校验
  2. 15位身份证号码校验(方法验证不准确)
  3. 15位转18位 身份证号码校验

18位身份证号合法性:

  • 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。
  • 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
  • 顺序码: 表示在同一地址码所标识的区域范围内,对同年、同月、同 日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配 给女性。
  • 前1、2位数字表示:所在省份的代码; 2.第3、4位数字表示:所在城市的代码; 3.第5、6位数字表示:所在区县的代码;
  • 第7~14位数字表示:出生年、月、日; 5.第15、16位数字表示:所在地的派出所的代码;
  • 第17位数字表示性别:奇数表示男性,偶数表示女性;
  • 第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。

3.代码

此工具类可以直接拷贝使用 并且提供了 main方法进行测试

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

351

352

353

354

355

356

357

358

359

360

361

362

363

364

365

366

367

368

369

370

371

372

373

374

375

376

377

378

379

380

381

382

383

384

385

386

387

388

389

390

391

392

393

394

395

396

397

398

399

400

401

402

403

404

405

406

407

408

409

410

411

412

413

414

415

416

417

418

419

420

421

422

423

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439
/**

* <p>

* 类说明:身份证合法性校验

* </p>

* <p>

* --15位身份证号码:第7、8位为出生年份(两位数),第9、10位为出生月份,第11、12位代表出生日期,第15位代表性别,奇数为男,偶数为女。

* --18位身份证号码:第7、8、9、10位为出生年份(四位数),第11、第12位为出生月份,第13、14位代表出生日期,第17位代表性别,奇数为男,偶数为女。

* </p>

*/

/**

* @Description: 身份证校验工具类

* @author: xuxinku

* @Date: 2020/9/07 10:55

* @ModifiedDate:

* @Copyright:xx保险股份有限公司

*/

@SuppressWarnings({"unchecked","unused","all"})

public class IdcardValidator {

/**

* 省,直辖市代码表: { 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:"澳门",91:"国外"}

*/

protected String codeAndCity[][] = { { "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", "澳门" },

{ "91", "国外" } };

private String cityCode[] = { "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", "91" };

// 每位加权因子

private int power[] = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };

// 第18位校检码

private String verifyCode[] = { "1", "0", "X", "9", "8", "7", "6", "5",

"4", "3", "2" };

/**

* 验证所有的身份证的合法性

* @param idcard

* @return

*/

public boolean isValidatedAllIdcard(String idcard) {

if (idcard.length() == 15) {

idcard = this.convertIdcarBy15bit(idcard);

}

return this.isValidate18Idcard(idcard);

}

/**

* <p>

* 判断18位身份证的合法性

* </p>

* 根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。

* 排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。

* <p>

* 顺序码: 表示在同一地址码所标识的区域范围内,对同年、同月、同 日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配 给女性。

* </p>

* <p>

* 1.前1、2位数字表示:所在省份的代码; 2.第3、4位数字表示:所在城市的代码; 3.第5、6位数字表示:所在区县的代码;

* 4.第7~14位数字表示:出生年、月、日; 5.第15、16位数字表示:所在地的派出所的代码;

* 6.第17位数字表示性别:奇数表示男性,偶数表示女性;

* 7.第18位数字是校检码:也有的说是个人信息码,一般是随计算机的随机产生,用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。

* </p>

* <p>

* 第十八位数字(校验码)的计算方法为: 1.将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7 9 10 5 8 4

* 2 1 6 3 7 9 10 5 8 4 2

* </p>

* <p>

* 2.将这17位数字和系数相乘的结果相加。

* </p>

* <p>

* 3.用加出来和除以11,看余数是多少?

* </p>

* 4.余数只可能有0 1 2 3 4 5 6 7 8 9 10这11个数字。其分别对应的最后一位身份证的号码为1 0 X 9 8 7 6 5 4 3

* 2。

* <p>

* 5.通过上面得知如果余数是2,就会在身份证的第18位数字上出现罗马数字的Ⅹ。如果余数是10,身份证的最后一位号码就是2。

* </p>

*

* @param idcard

* @return

*/

public boolean isValidate18Idcard(String idcard) {

// 非18位为假

if (idcard.length() != 18) {

return false;

}

// 获取前17位

String idcard17 = idcard.substring(0, 17);

// 获取第18位

String idcard18Code = idcard.substring(17, 18);

char c[] = null;

String checkCode = "";

// 是否都为数字

if (isDigital(idcard17)) {

c = idcard17.toCharArray();

} else {

return false;

}

if (null != c) {

int bit[] = new int[idcard17.length()];

bit = converCharToInt(c);

int sum17 = 0;

sum17 = getPowerSum(bit);

// 将和值与11取模得到余数进行校验码判断

checkCode = getCheckCodeBySum(sum17);

if (null == checkCode) {

return false;

}

// 将身份证的第18位与算出来的校码进行匹配,不相等就为假

if (!idcard18Code.equalsIgnoreCase(checkCode)) {

return false;

}

}

return true;

}

/**

* 验证15位身份证的合法性,该方法验证不准确,最好是将15转为18位后再判断,该类中已提供。

*

* @param idcard

* @return

*/

public boolean isValidate15Idcard(String idcard) {

// 非15位为假

if (idcard.length() != 15) {

return false;

}

// 是否全都为数字

if (isDigital(idcard)) {

String provinceid = idcard.substring(0, 2);

String birthday = idcard.substring(6, 12);

int year = Integer.parseInt(idcard.substring(6, 8));

int month = Integer.parseInt(idcard.substring(8, 10));

int day = Integer.parseInt(idcard.substring(10, 12));

// 判断是否为合法的省份

boolean flag = false;

for (String id : cityCode) {

if (id.equals(provinceid)) {

flag = true;

break;

}

}

if (!flag) {

return false;

}

// 该身份证生出日期在当前日期之后时为假

Date birthdate = null;

try {

birthdate = new SimpleDateFormat("yyMMdd").parse(birthday);

} catch (ParseException e) {

e.printStackTrace();

}

if (birthdate == null || new Date().before(birthdate)) {

return false;

}

// 判断是否为合法的年份

GregorianCalendar curDay = new GregorianCalendar();

int curYear = curDay.get(Calendar.YEAR);

int year2bit = Integer.parseInt(String.valueOf(curYear)

.substring(2));

// 判断该年份的两位表示法,小于50的和大于当前年份的,为假

if ((year < 50 && year > year2bit)) {

return false;

}

// 判断是否为合法的月份

if (month < 1 || month > 12) {

return false;

}

// 判断是否为合法的日期

boolean mflag = false;

curDay.setTime(birthdate); //将该身份证的出生日期赋于对象curDay

switch (month) {

case 1:

case 3:

case 5:

case 7:

case 8:

case 10:

case 12:

mflag = (day >= 1 && day <= 31);

break;

case 2: //公历的2月非闰年有28天,闰年的2月是29天。

if (curDay.isLeapYear(curDay.get(Calendar.YEAR))) {

mflag = (day >= 1 && day <= 29);

} else {

mflag = (day >= 1 && day <= 28);

}

break;

case 4:

case 6:

case 9:

case 11:

mflag = (day >= 1 && day <= 30);

break;

}

if (!mflag) {

return false;

}

} else {

return false;

}

return true;

}

/**

* 将15位的身份证转成18位身份证

*

* @param idcard

* @return

*/

public String convertIdcarBy15bit(String idcard) {

String idcard17 = null;

// 非15位身份证

if (idcard.length() != 15) {

return null;

}

if (isDigital(idcard)) {

// 获取出生年月日

String birthday = idcard.substring(6, 12);

Date birthdate = null;

try {

birthdate = new SimpleDateFormat("yyMMdd").parse(birthday);

} catch (ParseException e) {

e.printStackTrace();

}

Calendar cday = Calendar.getInstance();

cday.setTime(birthdate);

String year = String.valueOf(cday.get(Calendar.YEAR));

idcard17 = idcard.substring(0, 6) + year + idcard.substring(8);

char c[] = idcard17.toCharArray();

String checkCode = "";

if (null != c) {

int bit[] = new int[idcard17.length()];

// 将字符数组转为整型数组

bit = converCharToInt(c);

int sum17 = 0;

sum17 = getPowerSum(bit);

// 获取和值与11取模得到余数进行校验码

checkCode = getCheckCodeBySum(sum17);

// 获取不到校验位

if (null == checkCode) {

return null;

}

// 将前17位与第18位校验码拼接

idcard17 += checkCode;

}

} else { // 身份证包含数字

return null;

}

return idcard17;

}

/**

* 15位和18位身份证号码的基本数字和位数验校

*

* @param idcard

* @return

*/

public boolean isIdcard(String idcard) {

return idcard == null || "".equals(idcard) ? false : Pattern.matches(

"(^\\\\d{15}$)|(\\\\d{17}(?:\\\\d|x|X)$)", idcard);

}

/**

* 15位身份证号码的基本数字和位数验校

*

* @param idcard

* @return

*/

public boolean is15Idcard(String idcard) {

return idcard == null || "".equals(idcard) ? false : Pattern.matches(

"^[1-9]\\\\d{7}((0\\\\d)|(1[0-2]))(([0|1|2]\\\\d)|3[0-1])\\\\d{3}$",

idcard);

}

/**

* 18位身份证号码的基本数字和位数验校

*

* @param idcard

* @return

*/

public boolean is18Idcard(String idcard) {

return Pattern

.matches(

"^[1-9]\\\\d{5}[1-9]\\\\d{3}((0\\\\d)|(1[0-2]))(([0|1|2]\\\\d)|3[0-1])\\\\d{3}([\\\\d|x|X]{1})$",

idcard);

}

/**

* 数字验证

*

* @param str

* @return

*/

public boolean isDigital(String str) {

return str == null || "".equals(str) ? false : str.matches("^[0-9]*$");

}

/**

* 将身份证的每位和对应位的加权因子相乘之后,再得到和值

*

* @param bit

* @return

*/

public int getPowerSum(int[] bit) {

int sum = 0;

if (power.length != bit.length) {

return sum;

}

for (int i = 0; i < bit.length; i++) {

for (int j = 0; j < power.length; j++) {

if (i == j) {

sum = sum + bit[i] * power[j];

}

}

}

return sum;

}

/**

* 将和值与11取模得到余数进行校验码判断

*

* @param checkCode

* @param sum17

* @return 校验位

*/

public String getCheckCodeBySum(int sum17) {

String checkCode = null;

switch (sum17 % 11) {

case 10:

checkCode = "2";

break;

case 9:

checkCode = "3";

break;

case 8:

checkCode = "4";

break;

case 7:

checkCode = "5";

break;

case 6:

checkCode = "6";

break;

case 5:

checkCode = "7";

break;

case 4:

checkCode = "8";

break;

case 3:

checkCode = "9";

break;

case 2:

checkCode = "x";

break;

case 1:

checkCode = "0";

break;

case 0:

checkCode = "1";

break;

}

return checkCode;

}

/**

* 将字符数组转为整型数组

*

* @param c

* @return

* @throws NumberFormatException

*/

public int[] converCharToInt(char[] c) throws NumberFormatException {

int[] a = new int[c.length];

int k = 0;

for (char temp : c) {

a[k++] = Integer.parseInt(String.valueOf(temp));

}

return a;

}

public static void main(String[] args) throws Exception {

String idcard15 = "130503670401001";

String idcard18 = "321321198810113333";

String idcard = "130503670401001";

IdcardValidator iv = new IdcardValidator();

boolean flag = false;

flag = iv.isValidate18Idcard(idcard18);

System.out.println("18位身份证号校验"+flag);

flag = iv.isValidate15Idcard(idcard15);

System.out.println("15位身份证号校验"+ flag);

System.out.println("15位转18位身份证号" + iv.convertIdcarBy15bit(idcard15));

flag = iv.isValidate18Idcard(iv.convertIdcarBy15bit(idcard15));

System.out.println("15位转18位身份证号校验" + flag);

System.out.println(" 验证所有的身份证的合法性" + iv.isValidatedAllIdcard(idcard));

}

}

总结

到此这篇关于java身份证合法性校验工具类的文章就介绍到这了,更多相关java身份证合法性校验工具类内容请搜索快网idc以前的文章或继续浏览下面的相关文章希望大家以后多多支持快网idc!

原文链接:https://blog.csdn.net/xxk666/article/details/108470091

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 java身份证合法性校验工具类实例代码 https://www.kuaiidc.com/117464.html

相关文章

发表评论
暂无评论