اعتبارسنجی کد ملی، کارت بانکی، شبا و موبایل در فرمها
الگوریتمهای دقیق اعتبارسنجی دادههای ایرانی با کد آماده و تستشده؛ بهاضافهی نکتههایی که فرم را برای کاربر سادهتر میکند: ارقام فارسی، گروهبندی هنگام تایپ و زمان درست نمایش خطا.

تقریباً هر محصول ایرانی دیر یا زود فرمی دارد که کد ملی، شمارهی کارت، شبا یا موبایل میخواهد. و تقریباً هر تیم این اعتبارسنجیها را از نو مینویسد، معمولاً با یک عبارت باقاعدهی ساده که فقط تعداد رقمها را میشمارد.
این مقاله الگوریتمهای دقیق را با کد جاوااسکریپت آماده میدهد. همهی کدها پیش از انتشار تست شدهاند.
قدم اول: یکسان کردن ارقام
کاربران ارقام فارسی، عربی و لاتین را تایپ یا کپی میکنند. پیش از هر اعتبارسنجی، همه را لاتین کنید:
const toLatin = (s) =>
s.replace(/[۰-۹]/g, (d) => "۰۱۲۳۴۵۶۷۸۹".indexOf(d))
.replace(/[٠-٩]/g, (d) => "٠١٢٣٤٥٦٧٨٩".indexOf(d));
کد ملی
ده رقم که رقم آخر، رقم کنترل است. کد کوتاهتر از ده رقم را از سمت چپ با صفر پر کنید و کدهایی که همهی رقمهایشان یکی است را رد کنید:
function isNationalId(input) {
const id = toLatin(input).replace(/\D/g, "").padStart(10, "0");
if (id.length !== 10 || /^(\d)\1{9}$/.test(id)) return false;
const sum = [...id.slice(0, 9)].reduce((s, d, i) => s + Number(d) * (10 - i), 0);
const r = sum % 11;
return Number(id[9]) === (r < 2 ? r : 11 - r);
}
شمارهی کارت
شانزده رقم با الگوریتم Luhn، همان الگوریتمی که کارتهای بانکی همهجای دنیا دارند:
function isCard(input) {
const n = toLatin(input).replace(/\D/g, "");
if (n.length !== 16) return false;
let sum = 0;
for (let i = 0; i < 16; i++) {
let d = Number(n[i]);
if (i % 2 === 0) { d *= 2; if (d > 9) d -= 9; }
sum += d;
}
return sum % 10 === 0;
}
شش رقم اول کارت، بانک صادرکننده را مشخص میکند. نمایش نام یا لوگوی بانک کنار فیلد، به کاربر اطمینان میدهد شماره را درست وارد کرده است.

شبا
«IR» بهاضافهی ۲۴ رقم. چهار نویسهی اول به آخر منتقل میشوند، حرفها عدد میشوند (I=18، R=27) و باقیماندهی تقسیم کل عدد بر ۹۷ باید ۱ باشد. چون این عدد از دقت اعداد جاوااسکریپت بزرگتر است، باقیمانده را رقمبهرقم حساب کنید:
function isSheba(input) {
const s = toLatin(input).replace(/\s/g, "").toUpperCase();
if (!/^IR\d{24}$/.test(s)) return false;
const moved = s.slice(4) + "1827" + s.slice(2, 4);
let r = 0;
for (const ch of moved) r = (r * 10 + Number(ch)) % 97;
return r === 1;
}
موبایل
کاربران موبایل را به شکلهای مختلف مینویسند: «۰۹۱۲…»، «۹۱۲…»، «+۹۸۹۱۲…» و «۰۰۹۸۹۱۲…». همه را به یک شکل تبدیل کنید و بعد بسنجید:
function normalizeMobile(input) {
let m = toLatin(input).replace(/\D/g, "");
if (m.startsWith("0098")) m = m.slice(4);
else if (m.startsWith("98")) m = m.slice(2);
if (m.startsWith("9")) m = "0" + m;
return /^09\d{9}$/.test(m) ? m : null;
}
تجربهی کاربر، نه فقط الگوریتم
الگوریتم درست نصف کار است. نیمهی دیگر رفتار فیلد است:
- هر نوع رقمی را بپذیرید و فارسی نمایش دهید؛ لاتین ذخیره کنید.
- هنگام تایپ گروهبندی کنید: کارت ۴-۴-۴-۴ و شبا IR و گروههای چهارتایی، بدون اینکه مکاننما جابهجا شود.
- وقتی کاربر فیلد را ترک کرد اعتبارسنجی کنید، نه با هر کلید. خطای «کد ملی نامعتبر» بعد از تایپ رقم اول، آزاردهنده است.
- چیزی را که کاربر تایپ کرده پاک نکنید.
- پیام خطا بگوید چه کند: «کد ملی ۱۰ رقم است. رقمها را دوباره بررسی کنید.»


طراح محصول و سازندهی دیزاینسیستم کاشی. سایتهای زیادی را با هوش مصنوعی ساختهام و چند سال اخیر روی ایجنتیک کردن فرایندهای هوش مصنوعی کار کردهام. اسکیلهای این سایت همانهاییاند که خودم هر روز با آنها کار میکنم.
بیشتر دربارهی منچیزی که خواندید را همین امروز به دستیارتان بدهید
همهی این اسکیلها با لایسنس دائمی، بهروزرسانی رایگان برای همیشه و راهنمای نصب برای همهی ابزارها.
ساخت و توسعهی دیزاینسیستم فارسی
تجربهی ۲۱۵ کامیت ساخت کاشی در یک اسکیل: از توکن و RTL تا دادههای ایرانی، دسترسپذیری، تست تصویری و انتشار نسخه.
یوایکس رایتر فارسی
متن رابط سایت و اپ شما را بازنویسی میکند یا از صفر مینویسد: دکمه، خطا، حالت خالی، اعلان، لحن برند و درستنویسی.