How to Validate Iranian National Card Numbers with laravel-validate
Use the ValidNationalCard rule from the milwad-dev/laravel-validate package to validate 10-digit Iranian Melli Codes using the official government checksum algorithm.
The milwad-dev/laravel-validate package provides a robust, ready-to-use validation rule specifically designed for Iranian National Card numbers (also known as Melli Codes). This rule implements the standard Iranian national code checksum algorithm in src/Rules/ValidNationalCard.php, ensuring that user input conforms to the mathematical validation rules used by the Iranian National Organization for Civil Registration.
Understanding the ValidNationalCard Implementation
The validation logic resides in src/Rules/ValidNationalCard.php and implements Laravel’s Illuminate\Contracts\Validation\Rule contract. This design allows the rule to integrate seamlessly with request->validate(), Form Request classes, and manual Validator::make() calls without additional configuration.
The Iranian National Code Algorithm
The passes($attribute, $value) method executes a multi-layer validation sequence:
- Format validation: The input must match the regex
/^\d{10}$/, ensuring exactly ten digits with no letters or symbols. - Repetition check: The rule rejects strings consisting of a single repeated digit (e.g.,
1111111111) using the pattern/^(.)\1*$/u. - Checksum verification:
- Multiply each of the first nine digits by a decreasing weight from 10 down to 2 (position 1 × 10, position 2 × 9, etc.).
- Calculate the sum of these products and compute
sum % 11. - If the remainder is less than 2, it must equal the 10th digit; otherwise,
11 - remaindermust equal the 10th digit.
This algorithm matches the official validation used by Iranian government systems to detect typographical errors in national card numbers.
Class Structure and Error Handling
The class provides two required methods:
passes($attribute, $value): Returnstrueif the value passes all validation layers.message(): Returns the translation key__('validate.national-card'), allowing localization throughresources/lang/{locale}/validate.php.
The LaravelValidateServiceProvider registers the package’s translation namespace, ensuring the error message resolves correctly across locales.
Validating Iranian National Cards in Practice
Controller Validation
Use the rule directly within controller validation logic:
use Milwad\LaravelValidate\Rules\ValidNationalCard;
use Illuminate\Http\Request;
public function store(Request $request)
{
$validated = $request->validate([
'national_card' => ['required', new ValidNationalCard],
]);
// $validated['national_card'] contains a verified Iranian Melli Code
}
Form Request Classes
For cleaner controllers, implement the rule in a dedicated Form Request:
// app/Http/Requests/StoreUserRequest.php
use Milwad\LaravelValidate\Rules\ValidNationalCard;
use Illuminate\Foundation\Http\FormRequest;
class StoreUserRequest extends FormRequest
{
public function rules(): array
{
return [
'national_card' => ['required', new ValidNationalCard],
'name' => 'required|string',
];
}
}
Manual Validator Instances
When validating data outside of HTTP requests, use the Validator facade:
use Milwad\LaravelValidate\Rules\ValidNationalCard;
use Illuminate\Support\Facades\Validator;
$data = ['national_card' => '0151016437'];
$validator = Validator::make($data, [
'national_card' => ['required', new ValidNationalCard],
]);
if ($validator->fails()) {
// Handle invalid Iranian national card number
}
The test suite in tests/Rules/ValidNationalCardTest.php confirms that valid codes like 0151016437 pass, while invalid checksums like 0151016438 or malformed inputs like 101010 correctly fail validation.
Customizing Error Messages
The rule retrieves error messages using the translation key validate.national-card. Override this in your application’s language files to provide locale-specific feedback:
// resources/lang/fa/validate.php
return [
'national-card' => 'کد ملی وارد شده معتبر نیست.',
];
// resources/lang/en/validate.php
return [
'national-card' => 'The provided national card number is invalid.',
];
Place these files in resources/lang/{locale}/validate.php and Laravel will automatically resolve the appropriate message based on the application’s current locale.
Summary
- The
ValidNationalCardrule inmilwad-dev/laravel-validatevalidates 10-digit Iranian Melli Codes using the official checksum algorithm implemented insrc/Rules/ValidNationalCard.php. - The rule rejects repeated digits (e.g.,
1111111111) and validates the mathematical checksum of the first nine digits against the tenth control digit. - It implements Laravel’s
Rulecontract, enabling use in controllers, Form Requests, and manualValidatorinstances. - Error messages are customizable via the
validate.national-cardtranslation key inresources/lang/*/validate.php. - The package includes comprehensive unit tests in
tests/Rules/ValidNationalCardTest.phpcovering valid codes (0151016437) and invalid scenarios.
Frequently Asked Questions
What is the valid format for an Iranian national card number?
A valid Iranian national card number consists of exactly ten digits. The first nine digits form the unique identifier, while the tenth digit serves as a control number calculated using a weighted checksum algorithm. The ValidNationalCard rule enforces this 10-digit requirement and validates the checksum relationship.
Does this rule verify if the number is registered with the Iranian government?
No. The ValidNationalCard rule only performs syntactic and checksum validation to ensure the number follows the correct format and mathematical logic. It does not query government databases to confirm if the number is actively registered or assigned to a specific individual. For existence verification, you must integrate with official National Organization for Civil Registration APIs.
Can I use this rule alongside other Laravel validation rules?
Yes. Because ValidNationalCard implements Illuminate\Contracts\Validation\Rule, it composes naturally with standard Laravel validation rules. You can combine it with required, unique:users, or custom rules in the same validation array: 'national_card' => ['required', 'unique:users', new ValidNationalCard].
How do I change the error message for invalid national card numbers?
Publish or create a translation file at resources/lang/{locale}/validate.php and define the national-card key. The rule’s message() method returns __('validate.national-card'), so Laravel will automatically use your custom text when validation fails for that locale.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →