You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中如何校验AADHAR与PAN号码的有效性?

Flutter中AADHAR与PAN号码的校验及重新输入实现

一、号码有效性校验规则与实现

1. AADHAR号码校验

AADHAR的有效条件:

  • 必须是12位纯数字
  • 首位不能为0
  • 符合Luhn校验算法(印度AADHAR官方校验规则)

对应的Dart校验函数:

bool isValidAadhar(String aadhar) {
  // 校验长度、首位非0、全数字格式
  if (aadhar.length != 12 || !RegExp(r'^[1-9]\d{11}$').hasMatch(aadhar)) {
    return false;
  }
  
  // 执行Luhn算法校验
  int sum = 0;
  bool alternate = false;
  for (int i = aadhar.length - 1; i >= 0; i--) {
    int digit = int.parse(aadhar[i]);
    if (alternate) {
      digit *= 2;
      digit = digit > 9 ? (digit % 10) + 1 : digit;
    }
    sum += digit;
    alternate = !alternate;
  }
  return sum % 10 == 0;
}

2. PAN号码校验

PAN的有效格式:

  • 共10位字符
  • 前5位为大写英文字母(A-Z)
  • 中间4位为数字(0-9)
  • 最后1位为大写英文字母(A-Z)

对应的Dart校验函数:

bool isValidPan(String pan) {
  return RegExp(r'^[A-Z]{5}\d{4}[A-Z]$').hasMatch(pan);
}

二、错误提示与重新输入功能实现

在Flutter中,结合Form和TextFormField组件可快速实现输入校验、错误提示,以及让用户直接修改或清空重新输入的功能。

完整示例代码

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('AADHAR & PAN 校验')),
        body: const InputValidationForm(),
      ),
    );
  }
}

class InputValidationForm extends StatefulWidget {
  const InputValidationForm();

  @override
  State<InputValidationForm> createState() => _InputValidationFormState();
}

class _InputValidationFormState extends State<InputValidationForm> {
  final _formKey = GlobalKey<FormState>();
  final _aadharController = TextEditingController();
  final _panController = TextEditingController();

  @override
  void dispose() {
    _aadharController.dispose();
    _panController.dispose();
    super.dispose();
  }

  void _submitForm() {
    if (_formKey.currentState!.validate()) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('号码校验通过')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: Form(
        key: _formKey,
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            TextFormField(
              controller: _aadharController,
              keyboardType: TextInputType.number,
              decoration: const InputDecoration(
                labelText: 'AADHAR号码',
                hintText: '输入12位数字',
              ),
              validator: (value) {
                if (value == null || value.isEmpty) {
                  return '请输入AADHAR号码';
                }
                if (!isValidAadhar(value)) {
                  return '无效的AADHAR号码,请重新输入';
                }
                return null;
              },
            ),
            const SizedBox(height: 16),
            TextFormField(
              controller: _panController,
              textCapitalization: TextCapitalization.characters,
              decoration: const InputDecoration(
                labelText: 'PAN号码',
                hintText: '示例:ABCDE1234F',
              ),
              validator: (value) {
                if (value == null || value.isEmpty) {
                  return '请输入PAN号码';
                }
                if (!isValidPan(value)) {
                  return '无效的PAN号码,请重新输入';
                }
                return null;
              },
            ),
            const SizedBox(height: 24),
            ElevatedButton(
              onPressed: _submitForm,
              child: const Text('提交校验'),
            ),
          ],
        ),
      ),
    );
  }

  // AADHAR校验函数
  bool isValidAadhar(String aadhar) {
    if (aadhar.length != 12 || !RegExp(r'^[1-9]\d{11}$').hasMatch(aadhar)) {
      return false;
    }
    int sum = 0;
    bool alternate = false;
    for (int i = aadhar.length - 1; i >= 0; i--) {
      int digit = int.parse(aadhar[i]);
      if (alternate) {
        digit *= 2;
        digit = digit > 9 ? (digit % 10) + 1 : digit;
      }
      sum += digit;
      alternate = !alternate;
    }
    return sum % 10 == 0;
  }

  // PAN校验函数
  bool isValidPan(String pan) {
    return RegExp(r'^[A-Z]{5}\d{4}[A-Z]$').hasMatch(pan);
  }
}

功能细节说明

  • 提交表单时自动触发校验,无效输入会在输入框下方显示错误提示
  • 用户可直接在原输入框中修改内容,无需额外操作
  • 若需要快速清空输入,可给错误提示添加清空按钮,示例如下:
// 修改AADHAR输入框的validator和errorWidget
TextFormField(
  controller: _aadharController,
  keyboardType: TextInputType.number,
  decoration: const InputDecoration(
    labelText: 'AADHAR号码',
    hintText: '输入12位数字',
  ),
  validator: (value) {
    if (value == null || value.isEmpty) {
      return '请输入AADHAR号码';
    }
    if (!isValidAadhar(value)) {
      return ''; // 自定义错误组件时返回空文本
    }
    return null;
  },
  errorWidget: (errorText) {
    return Row(
      children: [
        const Text('无效的AADHAR号码'),
        const SizedBox(width: 8),
        InkWell(
          onTap: () => _aadharController.clear(),
          child: const Text(
            '清空重新输入',
            style: TextStyle(color: Colors.blue),
          ),
        ),
      ],
    );
  },
),

内容的提问来源于stack exchange,提问作者Kunal Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 16:13:22