目录

一、核心认知:18 位身份证的结构与验证维度

二、验证核心规则:从地区码到校验位的完整逻辑

2.1 地区码验证

2.2 出生日期验证

2.3 校验位验证(核心算法)

三、通用身份证验证器实战(鸿蒙端完整可运行代码)

3.1 核心验证函数(无依赖、通用)

3.2 鸿蒙端 UI 组件(输入 + 验证 + 结果展示)


一、核心认知:18 位身份证的结构与验证维度

18 位居民身份证号码的结构为 “6 位地区码 + 8 位出生日期 + 3 位顺序码 + 1 位校验位”,验证需覆盖 3 个核心维度:

号码段 含义 验证要点
第 1-6 位 地区行政区划代码 是否符合国家标准《GB/T 2260》
第 7-14 位 出生日期(YYYYMMDD) 年份 / 月份 / 日期是否合法(含闰年)
第 18 位 校验位(验证码) 是否符合 ISO 7064:1983.MOD 11-2 算法

二、验证核心规则:从地区码到校验位的完整逻辑

2.1 地区码验证

需匹配国家标准《GB/T 2260》中的有效行政区划代码(如110000对应北京市),实战中通过 “预设合法地区码列表” 判断有效性。

2.2 出生日期验证

需满足:

  1. 格式为YYYYMMDD(4 位年 + 2 位月 + 2 位日);
  2. 年份在合理范围(如 1900 - 当前年份);
  3. 月份为 1-12;
  4. 日期符合对应月份的天数(含闰年 2 月 29 天的判断)。

2.3 校验位验证(核心算法)

校验位通过ISO 7064:1983.MOD 11-2算法计算,步骤如下:

  1. 加权因子:[7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2](对应前 17 位);
  2. 前 17 位与加权因子相乘后求和,取结果对 11 的余数;
  3. 余数映射为校验位:0→1, 1→0, 2→X, 3→9, 4→8, 5→7, 6→6, 7→5, 8→4, 9→3, 10→2
  4. 映射结果与身份证第 18 位对比,一致则合法。

三、通用身份证验证器实战(鸿蒙端完整可运行代码)

3.1 核心验证函数(无依赖、通用)

包含 “地区码、出生日期、校验位” 全维度验证,返回结果与提示:

// 精简版省级行政区地区码(符合GB/T 2260标准)
const VALID_AREA_CODES = new Set([
  '110000', '120000', '130000', '140000', '150000', '210000', '220000', '230000',
  '310000', '320000', '330000', '340000', '350000', '360000', '370000', '410000',
  '420000', '430000', '440000', '450000', '460000', '500000', '510000', '520000',
  '530000', '540000', '610000', '620000', '630000', '640000', '650000', '810000',
  '820000'
]);

// 校验位加权因子
const WEIGHT_FACTOR = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
// 校验位映射表
const CHECK_CODE_MAP = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];

/**
 * 通用身份证验证函数
 * @param idCard 18位身份证号
 * @returns {isValid: boolean, message: string} 验证结果+提示
 */
const validateIdCard = (idCard) => {
  // 1. 格式初步检查
  if (!/^[1-9]\d{16}[\dXx]$/.test(idCard)) {
    return { isValid: false, message: '身份证号格式错误(需18位数字或最后一位X)' };
  }

  const idCardUpper = idCard.toUpperCase(); // 统一转大写(处理X/x)
  const areaCode = idCardUpper.slice(0, 6);
  const birthDateStr = idCardUpper.slice(6, 14);
  const checkCode = idCardUpper.slice(17, 18);

  // 2. 地区码验证
  if (!VALID_AREA_CODES.has(areaCode)) {
    return { isValid: false, message: '地区码无效,非国家标准行政区划代码' };
  }

  // 3. 出生日期验证
  const year = parseInt(birthDateStr.slice(0, 4), 10);
  const month = parseInt(birthDateStr.slice(4, 6), 10);
  const day = parseInt(birthDateStr.slice(6, 8), 10);
  const currentYear = new Date().getFullYear();

  if (year < 1900 || year > currentYear) return { isValid: false, message: '出生日期年份不合法' };
  if (month < 1 || month > 12) return { isValid: false, message: '出生日期月份不合法' };
  // 自动处理闰年的月份天数
  const maxDay = new Date(year, month, 0).getDate();
  if (day < 1 || day > maxDay) return { isValid: false, message: '出生日期日期不合法' };

  // 4. 校验位验证
  const sum = idCardUpper.slice(0, 17)
    .split('')
    .reduce((acc, digit, index) => acc + parseInt(digit, 10) * WEIGHT_FACTOR[index], 0);
  const mod = sum % 11;
  const calculatedCheckCode = CHECK_CODE_MAP[mod];

  if (checkCode !== calculatedCheckCode) {
    return { isValid: false, message: '校验位错误,身份证号不合法' };
  }

  return { isValid: true, message: '身份证号验证通过' };
};

3.2 鸿蒙端 UI 组件(输入 + 验证 + 结果展示)

贴合鸿蒙原生设计风格,实现输入框、验证按钮、实时结果提示:

import React, { useState } from 'react';
import { View, Text, TextInput, TouchableOpacity, StyleSheet } from 'react-native';

// (上方的VALID_AREA_CODES、WEIGHT_FACTOR等变量需在此处引入)

const IdCardValidatorDemo = () => {
  const [idCardInput, setIdCardInput] = useState('');
  const [validateResult, setValidateResult] = useState('请输入18位身份证号进行验证');
  const [resultColor, setResultColor] = useState('#666666');

  const handleValidate = () => {
    if (!idCardInput.trim()) {
      setValidateResult('请输入身份证号');
      setResultColor('#FF4444');
      return;
    }

    const { isValid, message } = validateIdCard(idCardInput);
    setValidateResult(message);
    setResultColor(isValid ? '#00C853' : '#FF4444');
  };

  return (
    <View style={styles.container}>
      <Text style={styles.pageTitle}>通用身份证验证器</Text>

      {/* 身份证输入框(鸿蒙端适配键盘) */}
      <TextInput
        style={styles.input}
        placeholder="请输入18位身份证号"
        placeholderTextColor="#999999"
        keyboardType="ascii-capable" // 支持数字+X
        value={idCardInput}
        onChangeText={setIdCardInput}
        maxLength={18} // 限制输入长度
      />

      {/* 验证按钮 */}
      <TouchableOpacity
        style={styles.validateBtn}
        onPress={handleValidate}
        activeOpacity={0.7}
      >
        <Text style={styles.btnText}>验证身份证号</Text>
      </TouchableOpacity>

      {/* 验证结果提示 */}
      <Text style={[styles.resultText, { color: resultColor }]}>
        {validateResult}
      </Text>
    </View>
  );
};

// 鸿蒙端适配样式
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#f7f8fa',
    paddingHorizontal: 20,
    gap: 25
  },
  pageTitle: {
    fontSize: 22,
    color: '#1a1a1a',
    fontWeight: '600',
    textAlign: 'center'
  },
  input: {
    width: '90%',
    height: 50,
    backgroundColor: '#fff',
    borderRadius: 8,
    paddingHorizontal: 15,
    fontSize: 16,
    borderWidth: 1,
    borderColor: '#e0e0e0'
  },
  validateBtn: {
    width: '90%',
    height: 50,
    backgroundColor: '#007DFF',
    borderRadius: 8,
    justifyContent: 'center',
    alignItems: 'center'
  },
  btnText: {
    fontSize: 17,
    color: '#fff',
    fontWeight: '500'
  },
  resultText: {
    fontSize: 15,
    textAlign: 'center',
    lineHeight: 22,
    width: '90%'
  }
});

export default IdCardValidatorDemo;

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐