iran-validation
v0.9.1
Published
Validate Iranian SHEBA (IBAN), national code & legal ID, bank card/BIN/Luhn, postal code, mobile & landline, vehicle plates (car/motorcycle), IMEI, passport, IPv4/IPv6. ESM, data bundled in-package.
Maintainers
Keywords
Readme
Iran Validation
A JavaScript (ESM) library to validate common Iranian identifiers: SHEBA (IBAN), national code (natural and legal national IDs), bank card, vehicle plate, IMEI, IPv4/IPv6 (optional Iranian-range check for IPv4), mobile (Iran-only subset of Phone), landline / mobile phone (Phone), postal code, passport number, and digit helpers.
- Node.js: >= 14
- Registry: iran-validation on npm
Data scope & updates
All metadata and lookup tables ship inside this package. Nothing here calls an external HTTP API at runtime—validation and hints (banks, BINs, area codes, operator prefixes, IPv4 ranges used for Iran, postal routing prefixes, plate/county mappings, national-code issuance regions, etc.) come from embedded data and algorithms.
That means:
- Figures such as
bankInfo,provinceInfo/cityInfo,isIranianfor IPv4, or plate geography reflect whatever version of the dataset is bundled in the npm release you installed, not a live national registry or carrier feed. - Rules that are purely algorithmic (e.g. Luhn/IMEI/SHEBA check digits, national-code checksums, passport shape) stay stable unless the spec or implementation changes.
- Tabular real-world assignments change over time—Ranges can be outdated, reorganized banks can share legacy BIN rows, postal or plate tables can lag official updates. Maintainer updates may arrive in future package versions; there is no promise that a given release matches “today” in every domain.
- For authoritative or legally binding decisions, rely on official sources and processes, not this library alone.
Installation
npm i iran-validationimport {
ShebaNumber,
PostalCode,
validatePostalCode,
validateBankCard,
IranPlate,
validateImei,
IranMobileNumber,
toEnglishDigits,
} from "iran-validation";Subpath imports
Each module can be imported directly (tree‑friendly):
| Symbol / topic | Import path |
|-----------------------|------------------------------------------|
| ShebaNumber | iran-validation/sheba |
| Phone | iran-validation/phone |
| NationalCode, IranNationalIdentifier, … | iran-validation/national-code |
| National ID façade | iran-validation/national-id |
| Bank card | iran-validation/bank-card |
| Car / motorcycle plate| iran-validation/car-number |
| IMEI | iran-validation/imei |
| IP | iran-validation/ip |
| Mobile | iran-validation/mobile |
| PassportNumber | iran-validation/passport-number |
| PostalCode | iran-validation/postal-code |
| toEnglishDigits | iran-validation/utils/toEnglishDigits |
Usage
SHEBA (ShebaNumber)
Iranian SHEBA follows ISO 13616 (IBAN check). Expected format for Iran: IR + 24 digits (26 characters total).
import { ShebaNumber, getIranBankByShebaCode } from "iran-validation";
// or: import ShebaNumber, { getIranBankByShebaCode } from "iran-validation/sheba";
const sheba = new ShebaNumber("IR840170000000343149119002");
sheba.isValid(); // boolean
// Persian / Arabic‑Indic digits are normalized automatically
sheba.englishForm; // "IR840170000000343149119002" (Latin digits, IR uppercase)
sheba.bankCode; // e.g. "017"
sheba.bankInfo; // { en_name, fa_name, code }
getIranBankByShebaCode("017"); // same shape as bankInfo when known
// Optional length override (non‑Iran IBAN experimentation)
sheba.shebaLength = 25;National code & national ID (NationalCode, IranNationalIdentifier, validateNationalId)
- Natural person: 10-digit national code (with optional zero-padding rules for shorter inputs).
- Legal entity: 11-digit national identifier; inferred when length is 11 unless you pass
{ kind: 'natural' | 'legal' }toIranNationalIdentifier/validateNationalIdentifier.
import {
NationalCode,
IranNationalIdentifier,
NationalIdentifierKind,
validateNationalIdentifier,
validateNationalId,
getNaturalNationalCodePlace,
} from "iran-validation";
// or from "iran-validation/national-code" / "iran-validation/national-id"
validateNationalIdentifier("5940041698"); // natural
validateNationalId("۱۰۳۸۰۱۷۴۷۸۵", { kind: NationalIdentifierKind.LEGAL }); // legal
const unified = new IranNationalIdentifier("5940041698");
unified.isValid();
unified.provinceInfo; // natural: FA/EN place hints from first 3 digits; legal: unknown
unified.cityInfo;
const nc = new NationalCode("5940041698"); // backwards-compatible: forces natural interpretation
nc.isValid();
getNaturalNationalCodePlace("5940041698"); // place row from first three digitsBank card (validateBankCard, IranBankCard)
Iranian 16-digit debit/credit-style numbers: optional Luhn (default true) and Iranian BIN table check (default iranianBinOnly: true).
import {
validateBankCard,
IranBankCard,
normalizeBankCardInput,
bankInfoFromCardBin,
} from "iran-validation";
// or from "iran-validation/bank-card"
validateBankCard("6037991111111112");
validateBankCard("4532015112830366", { iranianBinOnly: false });
const card = new IranBankCard("۶۰۳۷-۹۹۱۱ ۱۱۱۱ ۱۱۱۲");
card.englishForm; // "6037991111111112"
card.bankInfo; // via BIN → SHEBA map or inline BIN table
card.isValid();Vehicle plate (IranPlate, validateCarNumber)
- Car / public: normalized pattern
two digits + Persian letter + three digits + two-digit province code(e.g.66ق66611). - Motorcycle: eight consecutive digits
three-digit area + five-digit serial.
Persian letter variants and separators are normalized.
import { IranPlate, validateCarNumber, normalizePlateInput } from "iran-validation";
// or from "iran-validation/car-number"
validateCarNumber("66ق66611");
validateCarNumber("11112345", { kinds: ["motorcycle"] });
const plate = new IranPlate("۶۶ ق ۶۶۶ ۱۱");
plate.normalized;
plate.kind; // "car" | "motorcycle" | null
plate.isValid();
plate.provinceInfo; // { fa_name }
plate.cityInfo; // { fa_name }
plate.details;IMEI (validateImei, normalizeImeiInput)
15-digit GSMA-style IMEI with Luhn check digit (default enabled; pass { luhn: false } for length/digits-only).
import { validateImei, normalizeImeiInput } from "iran-validation";
// or from "iran-validation/imei"
validateImei("490154203237518");
validateImei("۴۹۰۱۵۴۲۰۳۲۳۷۵۱۸");IP address (IranIpAddress, validateIp)
Valid IPv4 or IPv6 literals. Iranian geo uses aggregated IPv4 ranges (no IPv6 country data in-library → isIranian is false for IPv6).
import {
validateIp,
IranIpAddress,
getIpVersion,
isIranianIp,
} from "iran-validation";
// or from "iran-validation/ip"
validateIp("185.143.232.1", { country: "IR" });
validateIp("2001:db8::1", { version: "ipv6" });
const ip = new IranIpAddress("185.143.232.1");
ip.version;
ip.normalized;
ip.isIranian;Mobile only (IranMobileNumber, validateMobile)
Same input shapes as Phone, but accepts only Iranian mobile lines (landlines fail).
import {
validateMobile,
IranMobileNumber,
getMobileOperatorInfo,
} from "iran-validation";
// or from "iran-validation/mobile"
validateMobile("+989115555555");
const m = new IranMobileNumber("09115555555");
m.operatorInfo; // { fa_name, en_name }
m.nationalFormat;
getMobileOperatorInfo("09121987654");Phone (Phone)
Default export class is PhoneNumber; the main package exposes it as Phone.
Supports mobile (09…) and landline (021…, 009821…, +9821…, …). Persian / Arabic‑Indic digits and spaces are normalized.
import { Phone } from "iran-validation";
// or: import Phone from "iran-validation/phone";
const mobile = new Phone("+989115555555");
mobile.phoneType; // "mobile" | "landline" | "invalid"
mobile.isValid(); // boolean
mobile.cleanNumber; // national significant digits without country/trunk (e.g. "9115555555" or "2188776655")
mobile.operationCode; // mobile: operator prefix "911"; landline: area code without trunk "21"
mobile.phoneInfo; // mobile: { codeName, operationName }; landline: { codeName: "Landline", operationName (FA city), cityEn }
mobile.cityInfo; // landline only: { fa_name, en_name }; mobile: null
mobile.englishForm; // "989115555555" or "982188776655" when valid
mobile.nationalFormat; // "09115555555" or "02188776655" when validLandline example (Tehran):
const fixed = new Phone("02188776655");
// or: new Phone("00982188776655"), new Phone("+982188776655")
fixed.phoneType; // "landline"
fixed.cityInfo; // { fa_name: "تهران", en_name: "Tehran" }Accepted mobile shapes include +98…, 0098…, 098…, leading 0, national significant only, and optional dashes.
Landline validation uses a prefix table of Iranian area codes (approximate; subscriber length 5–8 digits after the area code).
Postal code (PostalCode / validatePostalCode)
Iran uses 10-digit postal codes. Spaces and dashes are ignored; Persian / Arabic‑Indic digits are converted.
import { PostalCode, validatePostalCode } from "iran-validation";
// or: import PostalCode, { validatePostalCode } from "iran-validation/postal-code";
validatePostalCode("1496714313"); // boolean
const pc = new PostalCode("۱۴۹۶۷۱۴۳۱۳"); // Persian digits OK
pc.isValid();
pc.code; // normalized 10-digit string (Latin digits)
pc.routingArea; // first 5 digits (string)
pc.provinceInfo; // { fa_name, en_name } — approximate from routing prefix tables
pc.regionInfo; // { fa_name, en_name } — city / postal zone / province labelRegion lookup is based on published routing-prefix ranges and may not match every edge case.
Passport number (PassportNumber)
Official-style Iranian passports use one Latin letter + eight digits. On the Persian data page only eight digits may appear (without the letter); enable that with { digitsOnly: true }.
import {
PassportNumber,
validatePassportNumber,
normalizePassportInput,
} from "iran-validation";
validatePassportNumber("A12345678"); // true
validatePassportNumber("۱۲۳۴۵۶۷۸", { digitsOnly: true }); // true
const pp = new PassportNumber("a87654321");
pp.isValid(); // true
pp.englishForm; // "A87654321"Helper: toEnglishDigits
Converts Persian (۰–۹) and Arabic‑Indic (٠–٩) digits to Latin 0–9; other characters are unchanged.
import { toEnglishDigits } from "iran-validation";
// or: import { toEnglishDigits } from "iran-validation/utils/toEnglishDigits";
toEnglishDigits("۰۱۲۳"); // "0123"API summary
| Export / symbol | Role |
|-----------------|------|
| ShebaNumber, getIranBankByShebaCode | SHEBA / IBAN + bank metadata |
| NationalCode, IranNationalIdentifier, validateNationalIdentifier, NationalIdentifierKind, validateNationalId, place helpers | Natural + legal national IDs |
| Phone | Mobile + landline |
| validateMobile, IranMobileNumber, getMobileOperatorInfo | Mobile-only wrapper |
| validateBankCard, IranBankCard, normalizeBankCardInput, bankInfoFromCardBin, BIN maps | 16-digit card + BIN |
| validateCarNumber, IranPlate, normalizePlateInput | Car + motorcycle plates |
| validateImei, normalizeImeiInput | 15-digit IMEI + Luhn |
| validateIp, IranIpAddress, getIpVersion, isIranianIp | IPv4/v6 + optional IR IPv4 |
| PostalCode, validatePostalCode | 10-digit postal code + region hints |
| PassportNumber, validatePassportNumber, normalizePassportInput | Passport formats |
| toEnglishDigits | Digit normalization |
License
ISC — see LICENSE.
