Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Check Iranian National Code Validity - بررسی صحت کد ملی ایرانی - Clojure, C#, Ruby, JavaScript, Dart, Python, Scala, Java 8, PHP, C, Go, Swift, Kotlin, Groovy, Rust, Haskell, Erlang, Elixir
// Check Iranian National Code Validity - Clojure, C#, Ruby, JavaScript, Dartm Python, Scala, Java 8, PHP, C, Go, Swift, Kotlin, Groovy, Rust, Haskell, Erlang, Elixir
// بررسی صحت کد ملی ایران - کلوژر، سی‌شارپ، روبی، جاوااسکریپت، دارت، پایتون، اسکالا، جاوا ۸، پی‌اچ‌پی، سی، گو، سوئیفت، کاتلین، گرووی، راست، هسکل، ارلنگ، الکسیر
// در نسخه‌های قبل یکسان بودن اعداد نا معتبر تشخیص داده می‌شد ولی
// اعداد یکسان نامعتبر نیست http://www.fardanews.com/fa/news/127747
// بعضی از پیاده‌سازی‌ها سریع نیستند، می‌توانید نسخهٔ خود را بر پایهٔ
// نسخهٔ سی یا گو ایجاد کنید که بهترین سرعت را داشته باشد
/**
* @author Ebrahim Byagowi (2013-)
* @license: Public Domain
*/
// Clojure
(defn valid-iran-code? [input]
(if (re-matches #"^\d{10}$" input)
(let
[check (Integer/parseInt (subs input 9 10))
sum (mod (reduce + (map (fn [x] (* (Integer/parseInt
(subs
input x (+ x 1)))
(- 10 x)))
(range 9))) 11)]
(or (and (< sum 2) (== check sum))
(and (>= sum 2) (== (+ check sum) 11))))
false))
// Ruby
def is_valid_iran_code(input)
return false if /^\d{10}$/ !~ input
check = Integer(input[9])
s = (0..8).map{|x| Integer(input[x]) * (10 - x)}.inject(:+) % 11
(s < 2 && check == s) || (s >= 2 && check + s == 11)
end
// C#
using System.Text.RegularExpressions;
public static bool IsValidIranianNationalCode(string input)
{
if (!Regex.IsMatch(input, @"^\d{10}$"))
return false;
var check = Convert.ToInt32(input.Substring(9, 1));
var sum = Enumerable.Range(0, 9)
.Select(x => Convert.ToInt32(input.Substring(x, 1)) * (10 - x))
.Sum() % 11;
return (sum < 2 && check == sum) || (sum >= 2 && check + sum == 11);
}
// JavaScript
function isValidIranianNationalCode(input) {
if (!/^\d{10}$/.test(input))
return false;
var check = +input[9];
var sum = 0;
var i;
for (i = 0; i < 9; ++i) {
sum += +input[i] * (10 - i);
}
sum %= 11;
return (sum < 2 && check == sum) || (sum >= 2 && check + sum == 11);
}
// ES6
function isValidIranianNationalCode(input) {
if (!/^\d{10}$/.test(input))
return false;
const check = +input[9];
const sum = Array(9).fill().map((_, i) => +input[i] * (10 - i)).reduce((x, y) => x + y) % 11;
return (sum < 2 && check == sum) || (sum >= 2 && check + sum == 11);
}
// Dart
bool isValidIranianNationalCode(String input) {
if (!RegExp("^\\d{10}").hasMatch(input)) return false;
final check = int.parse(input[9]);
final sum = Iterable<int>.generate(9).map((x) => int.parse(input[x]) * (10 - x)).reduce((x, y) => x + y) % 11;
return (sum < 2 && check == sum) || (sum >= 2 && check + sum == 11);
}
// C
bool isValidIranianNationalCode(const char *input) {
for (int i = 0; i < 10; ++i) if (input[i] < '0' || input[i] > '9') return false;
int check = input[9] - '0';
int sum = 0;
for (int i = 0; i < 9; ++i) sum += (int)(input[i] - '0') * (10 - i);
sum %= 11;
return (sum < 2 && check == sum) || (sum >= 2 && check + sum == 11);
}
// Go
func isValidIranianNationalCode(input string) bool {
for i := 0; i < 10; i++ {
if input[i] < '0' || input[i] > '9' {
return false
}
}
check := int(input[9] - '0')
sum := 0
for i := 0; i < 9; i++ {
sum += int(input[i]-'0') * (10 - i)
}
sum %= 11
return (sum < 2 && check == sum) || (sum >= 2 && check+sum == 11)
}
// Python
import re
def is_valid_iran_code(input):
if not re.search(r'^\d{10}$', input):
return False
check = int(input[9])
s = sum([int(input[x]) * (10 - x) for x in range(9)]) % 11
return (s < 2 and check == s) or (s >= 2 and check + s == 11)
// Scala
def isValidIranianNationalCode(input: String) = {
val pattern = """^(\d{10})$""".r
input match {
case pattern(_) =>
val check = input.substring(9, 10).toInt
val sum = (0 to 8)
.map(x => input.substring(x, x + 1).toInt * (10 - x))
.sum % 11
(sum < 2 && check == sum) || (sum >= 2 && check + sum == 11)
case _ => false
}
}
// Java 8
import java.util.stream.Streams;
import java.util.function.IntUnaryOperator;
public static boolean isValidIranianNationalCode(String input) {
if (!input.matches("^\\d{10}$"))
return false;
int check = Integer.parseInt(input.substring(9, 10));
int sum = IntStream.range(0, 9)
.map(x -> Integer.parseInt(input.substring(x, x + 1)) * (10 - x))
.sum() % 11;
return (sum < 2 && check == sum) || (sum >= 2 && check + sum == 11);
}
// PHP
function isValidIranianNationalCode($input) {
if (!preg_match("/^\d{10}$/", $input)) {
return false;
}
$check = (int) $input[9];
$sum = array_sum(array_map(function ($x) use ($input) {
return ((int) $input[$x]) * (10 - $x);
}, range(0, 8))) % 11;
return ($sum < 2 && $check == $sum) || ($sum >= 2 && $check + $sum == 11);
}
// Swift, based on @farzadshbfn work but modified a little, tested with Swift 5.3.1
func isValidIranianNationalCode(input: String) -> Bool {
let digits = input.compactMap { Int(String($0)) }
guard digits.count == 10 && digits.count == input.count else {
return false
}
let check = digits[9]
let sum = digits[0 ..< 9].enumerated().reduce(0) { $0 + $1.element * (10 - $1.offset) } % 11
return sum < 2 ? check == sum : check + sum == 11
}
// Kotlin, Android
fun isValidIranianNationalCode(input: String): Boolean {
if (!"^\\d{10}$".toRegex().matches(input))
return false
input.toCharArray().map(Character::getNumericValue).let {
val check = it[9]
val sum = (0..8).map { i -> it[i] * (10 - i) }.sum() % 11
return sum < 2 && check == sum || sum >= 2 && check + sum == 11
}
}
// Groovy, based on @mehrali work
boolean isValidIranianNationalCode(String input) {
if (!input?.matches('^\\d{10}$'))
return false
int check = input[9].toInteger()
int sum = (0..8).sum({ input[it].toInteger() * (10 - it) }) % 11
return ((sum < 2 && check == sum) || (sum >= 2 && check + sum == 11))
}
// Rust
fn is_valid_iranian_national_code(s: &str) -> bool {
let digits: Vec<u32> = s.chars()
.filter_map(|x| x.to_digit(10))
.collect();
if digits.len() != 10 { return false }
let check = digits[9];
let sum = (0..9).map(|x| digits[x] * (10 - x) as u32).sum::<u32>() % 11;
(sum < 2 && check == sum) || (sum >= 2 && check + sum == 11)
}
// Haskell, contributed by @hzamani
import Data.Char
isValidNationalCode code =
length code == 10 && all isDigit code && if s < 2 then check == s else check + s == 11
where
digits = map digitToInt code
check = last digits
s = sum (map (\(d, i) -> d * (10 - i)) $ digits `zip` [0..8]) `mod` 11
// Erlang, contributed by @hzamani
is_valid_national_code(Code) ->
length(Code) == 10
andalso lists:all(fun(D) -> $0 =< D andalso D =< $9 end, Code)
andalso begin
ToDigit = fun(Char) -> Char - $0 end,
S = lists:sum(lists:map(fun({I, D}) -> D * (10 - I) end, lists:zip(lists:seq(0, 8), lists:droplast(lists:map(ToDigit, Code))))) rem 11,
Check = ToDigit(lists:last(Code)),
if
S < 2 -> Check == S;
true -> Check + S == 11
end
end.
// Elixir, contributed by @hzamani
fn input ->
if input =~ ~r/^\d{10}$/ do
[check | digits] =
input
|> String.split("", trim: true)
|> Enum.map(&String.to_integer/1)
|> Enum.reverse
s =
digits
|> Enum.with_index(2)
|> Enum.map(fn {digit, i} -> digit * i end)
|> Enum.sum
|> rem(11)
if s < 2 do check == s else check + s == 11 end
else
false
end
end
@amirkarimi

This comment has been minimized.

Copy link

@amirkarimi amirkarimi commented Dec 25, 2014

Scala code doesn't work. """^\d{10}$""".r should become """^(\d{10})$""".r.

@ghasemy50

This comment has been minimized.

Copy link

@ghasemy50 ghasemy50 commented Mar 25, 2017

عالی دمت گرم واقعا زحمت کشیدی :-)

@qasimsina

This comment has been minimized.

Copy link

@qasimsina qasimsina commented Aug 2, 2017

@Lithium-HD
Your code doesn't work in Swift 3!

@Elias-Heydarpour

This comment has been minimized.

Copy link

@Elias-Heydarpour Elias-Heydarpour commented Nov 27, 2017

thanks,
very good!

@koctodox

This comment has been minimized.

Copy link

@koctodox koctodox commented Feb 9, 2018

You are hero !!!

@alireza267

This comment has been minimized.

Copy link

@alireza267 alireza267 commented Feb 18, 2018

Excellent! thanks a lot.

@Mhs-220

This comment has been minimized.

Copy link

@Mhs-220 Mhs-220 commented Apr 10, 2018

Thank You! it's very helpful

@hamed2867

This comment has been minimized.

Copy link

@hamed2867 hamed2867 commented Aug 7, 2018

سپاسگزار از زحمات شما، عالی بود

@ebraminio

This comment has been minimized.

Copy link
Owner Author

@ebraminio ebraminio commented Oct 8, 2018

بعد از سال‌ها این اسکریپت دوباره به کارم آمد و نسخهٔ کاتلینش را اضافه کردم :)

@vmohir

This comment has been minimized.

Copy link

@vmohir vmohir commented Feb 20, 2019

In ES6, the fill method needs has 1-3 arguments. you need to change Array(9).fill() to Array(9).fill(undefined).
Or I prefer to use this code instead:

Array.from(new Array(9), (_, i) => +input[i] * (10 - i)).reduce((x, y) => x + y) % 11
@ebraminio

This comment has been minimized.

Copy link
Owner Author

@ebraminio ebraminio commented Apr 4, 2019

@dehghani-mehdi @iMojtaba @aghasoroush توضیح بالای کد را یک بررسی مجدد کنید، ممنونم

@ebraminio

This comment has been minimized.

Copy link
Owner Author

@ebraminio ebraminio commented Apr 4, 2019

@mehrali @sparse91 اعمال شد :)

@mahdigh99

This comment has been minimized.

Copy link

@mahdigh99 mahdigh99 commented Aug 5, 2019

ورژن جاوااسکریپت کار نمیکنه! هر چی میدی غلط تشخیص میده حتی ۱۱۱۱۱۱۱۱۱۱

@ebraminio

This comment has been minimized.

Copy link
Owner Author

@ebraminio ebraminio commented Aug 5, 2019

لطفاً از نوع رشته ارسال کنید چون بعضی از شماره ملی‌ها دارای صفر در اول هستند و اعداد به نظر ورودی درستی نباشن برای همچین کاری، ممنون

@mahdigh99

This comment has been minimized.

Copy link

@mahdigh99 mahdigh99 commented Aug 5, 2019

ممنونم
توی کنسول حل شد اما توی پروژم به طرز عجیبی همچنان نمیشه
مشکل هم از همون تعداد اوله با اینکه دقیقا تعداد ارقامش ۱۰ تاست ولی بازم فالس میده

@mahdigh99

This comment has been minimized.

Copy link

@mahdigh99 mahdigh99 commented Aug 6, 2019

مشکلم حل شد
مشکل از اونجا بود که وقتی از
template engine
استفاده میکنی مرورگر بک اسلش ها رو اسکیپ میکنه
باید با همچین حالتی بنویسی تا اوکی بشه
/^\\d{10}$/

if (!/^\d{10}$/.test(input)) ===> if (!/^\\d{10}$/.test(input))

@ebraminio

This comment has been minimized.

Copy link
Owner Author

@ebraminio ebraminio commented Aug 17, 2019

این کد اصلی این صفحه نیست، شرط اعداد برابر نادرست است (و این بدترین شیوهٔ بررسی آن است، می‌توان آن را در همان عبارت باقاعدهٔ اصلی چا کرد) و در بالای صفحهٔ توضیح داده شده که چرا، اگر کاربرتان نمی‌خواهد اعداد واقعی دهد چه این شرط را بگذارید چه نه به شما اعداد واقعی نخواهد داد و آخر راهی برای دادن اعداد اشتباه پیدا خواهد کرد

@masoudlotfi

This comment has been minimized.

Copy link

@masoudlotfi masoudlotfi commented Dec 7, 2019

Hi Ebrahim.
Thanks for share this code with us.But it has one problem for java code.
I run my test and i found this problem.
For nationalCode = ''0000000000", "1111111111" this code return True But should return false.

@ebraminio

This comment has been minimized.

Copy link
Owner Author

@ebraminio ebraminio commented Dec 7, 2019

Why it should, it was doing but removed after http://www.fardanews.com/fa/news/127747 years ago

@ebraminio

This comment has been minimized.

Copy link
Owner Author

@ebraminio ebraminio commented Jan 26, 2020

سلام گرامی خواستید دو کد جاوااسکریپت موجود در همین صفحه که همین کار را با تعداد کمتری دستور و
http://www.fardanews.com/fa/news/127747
این خبر را هم نگاهی بیاندازید، عملکرد پد
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
هم مدت خوبی است به مرورگرها اضافه شده خواستید می‌توانید از آن استفاده کنید، ممنونم

@maysam

This comment has been minimized.

Copy link

@maysam maysam commented Jan 26, 2020

ممنون
درسته
خودم از همین استفاده می کنیم
برای تایپ اسکریپتش زدم

@ahbanavi

This comment has been minimized.

Copy link

@ahbanavi ahbanavi commented Jan 9, 2021

Thx

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment