-
-
Save MMnasrabadi/c35337677c2d368dab967eeab685ff75 to your computer and use it in GitHub Desktop.
Check Iranian National Code Validity - بررسی صحت کد ملی ایرانی - Clojure, C#, Ruby, JavaScript, Python, Scala, Java 8, PHP, C, Go, Swift, Kotlin, Groovy, Rust, Haskell, Erlang, Elixir
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Check Iranian National Code Validity - Clojure, C#, Ruby, JavaScript, 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 = parseInt(input[9]); | |
var sum = 0; | |
var i; | |
for (i = 0; i < 9; ++i) { | |
sum += parseInt(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; | |
var check = +input[9]; | |
var 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); | |
} | |
// 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 3, based on @farzadshbfn work but modified a little | |
func isValidIranianNationalCode(input: String) -> Bool { | |
var digits = input.characters.flatMap { 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment