-
Star
(175)
You must be signed in to star a gist -
Fork
(24)
You must be signed in to fork a gist
-
-
Save ebraminio/5292017 to your computer and use it in GitHub Desktop.
| // Check Iranian National Code Validity - Clojure, C#, F#, Ruby, JavaScript, Dart, Python, Scala, Java 8, PHP, C, Go, Swift, Kotlin, Groovy, Rust, Haskell, Erlang, Elixir, Power Query M Language, VBA, R, Lua, Fortran, Pascal/Delphi, Excel, Stored Procedure / MySQL | |
| // بررسی صحت کد ملی ایران - کلوژر، سیشارپ، افشارپ، روبی، جاوااسکریپت، دارت، پایتون، اسکالا، جاوا ۸، پیاچپی، سی، گو، سوئیفت، کاتلین، گرووی، راست، هسکل، ارلنگ، الکسیر، پاورکوئری ام، ویبی ای، آر، لوآ، فرترن، پاسکال/دلفی، اکسل، مایاسکیوال | |
| // در نسخههای قبل یکسان بودن اعداد نا معتبر تشخیص داده میشد ولی | |
| // اعداد یکسان نامعتبر نیست https://web.archive.org/web/20170706081048/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)] | |
| (if (< sum 2) (== check sum) (== (+ check sum) 11)) | |
| false)) | |
| // Ruby | |
| def is_valid_iran_code(input) | |
| return false if /^\d{10}$/ !~ input | |
| check = Integer(input[9]) | |
| s = (0..8).sum {|x| Integer(input[x]) * (10 - x)} % 11 | |
| s < 2 ? check == s : 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 : check + sum == 11; | |
| } | |
| // F# | |
| open System.Text.RegularExpressions | |
| let isValidIranianNationalCode input = | |
| if Regex.IsMatch(input, @"^\d{10}$") then | |
| let check = Convert.ToInt32(input.Substring(9, 1)) | |
| let sum = (seq { 0 .. 8 } | |
| |> Seq.map (fun x -> Convert.ToInt32(input.Substring(x, 1)) * (10 - x)) | |
| |> Seq.sum) % 11 | |
| if sum < 2 then check = sum else check + sum = 11 | |
| else | |
| false | |
| // JavaScript | |
| function isValidIranianNationalCode(input) { | |
| if (!/^\d{10}$/.test(input)) return false; | |
| const check = +input[9]; | |
| const sum = input.split('').slice(0, 9).reduce((acc, x, i) => acc + +x * (10 - i), 0) % 11; | |
| return sum < 2 ? check === sum : 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 : check + sum == 11; | |
| } | |
| // C | |
| bool isValidIranianNationalCode(const char *input) { | |
| for (unsigned i = 0; i < 10; ++i) if (input[i] < '0' || input[i] > '9') return false; | |
| if (input[10]) return false; | |
| unsigned check = input[9] - '0'; | |
| unsigned sum = 0; | |
| for (unsigned i = 0; i < 9; ++i) sum += (int)(input[i] - '0') * (10 - i); | |
| sum %= 11; | |
| return sum < 2 ? check == sum : 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: str) -> bool: | |
| 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 check == s if s < 2 else 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 | |
| if (sum < 2) check == sum else 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 : check + sum == 11; | |
| } | |
| // PHP | |
| function isValidIranianNationalCode(string $input): boolean { | |
| 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 : $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 | |
| fun isValidIranianNationalCode(input: String): Boolean { | |
| if (input.length != 10) return false | |
| val digits = input.mapNotNull(Char::digitToIntOrNull).takeIf { it.size == 10 } ?: return false | |
| val check = digits[9] | |
| val sum = digits.slice(0..8).asSequence().mapIndexed { i, x -> x * (10 - i) }.sum() % 11 | |
| return if (sum < 2) check == sum else 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 : 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 s.len() != 10 || digits.len() != 10 { | |
| return false; | |
| } | |
| let check = digits[9]; | |
| let sum = (0..9).map(|x| digits[x] * (10 - x) as u32).sum::<u32>() % 11; | |
| if sum < 2 { | |
| check == sum | |
| } else { | |
| 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 | |
| // PowerQuery M Language, in a collaboration with Calak | |
| (input as text) as logical => | |
| let | |
| check = Number.From(Text.End(input, 1)), | |
| s = Number.Mod(List.Sum(List.Transform({0..8}, each (10 - _) * Number.From(Text.At(input, _)))), 11) | |
| in Text.Length(input) = 10 and | |
| Text.Select(input, {"0".."9"}) = input and | |
| (if s < 2 then check = s else check + s = 11) | |
| // VBA, in a collaboration with Calak | |
| Public Function IsValidIranianNationalCode(code As String) As Boolean | |
| If Not code Like String(10, "#") Then Exit Function | |
| Dim check As Byte, i As Byte, s As Integer | |
| check = Mid(code, 10) | |
| For i = 1 To 9 | |
| s = s + (11 - i) * Mid(code, i, 1) | |
| Next i | |
| s = s Mod 11 | |
| IsValidIranianNationalCode = IIf(s < 2, check = s, check + s = 11) | |
| End Function | |
| // R, by Calak | |
| is_valid_iran_code <- function(input) { | |
| if (!grepl('^[0-9]{10}$', input)) return (FALSE) | |
| check <- as.integer(substr(input, 10, 10)) | |
| s <- t(10:2) %*% as.integer(unlist(strsplit(input, "")))[-10] %% 11 | |
| return (if (s < 2) check == s else check + s == 11) | |
| } | |
| // Lua | |
| function is_valid_iranian_national_code(input) | |
| if input:match(string.rep("%d", 10)) ~= input then return false end | |
| local check = tonumber(input:sub(10, 10)) | |
| local sum = 0 | |
| for i = 1, 9 do | |
| sum = sum + (11 - i) * tonumber(input:sub(index, index)) | |
| end | |
| sum = sum % 11 | |
| return (sum < 2) and (check == sum) or (check + sum == 11) | |
| end | |
| // Fortran, by Calak | |
| logical pure function is_valid_iranian_national_code(input) | |
| character(10), intent(in) :: input; integer :: check, i, s | |
| integer, parameter :: zero = ichar("0") | |
| is_valid_iranian_national_code = .false. | |
| if (verify(input, "0123456789") /= 0) return | |
| check = ichar(input(10:)) - zero | |
| s = mod(sum((/ ((11 - i) * (ichar(input(i:i)) - zero), i = 1, 9) /)), 11) | |
| is_valid_iranian_national_code = merge(check == s, check + s == 11, s < 2) | |
| end function is_valid_iranian_national_code | |
| // Pascal/Delphi, by Calak | |
| function isValidIranianNationalCode(input: string): boolean; | |
| const s: integer = 0; | |
| var check, i: byte; | |
| begin | |
| isValidIranianNationalCode := false; | |
| if ord(input[0]) <> 10 then exit; | |
| for i := 1 to 10 do if not (input[i] in ['0'..'9']) then exit; | |
| val(input[10], check); | |
| for i := 1 to 9 do inc(s, (11 - i) * (ord(input[i]) - ord('0'))); | |
| s := s mod 11; | |
| isValidIranianNationalCode := ((s < 2) and (check = s) or (s >= 2) and (check + s = 11)); | |
| end; | |
| // Excel 365, by Calak | |
| = LAMBDA(input, | |
| IF( | |
| AND(LEN(input) = 10, ISNUMBER(--MID(input, SEQUENCE(10), 1))), | |
| LET( | |
| check, --RIGHT(input), | |
| s, MOD(SUMPRODUCT(SEQUENCE(9, 1, 10, -1), --MID(input, SEQUENCE(9), 1)), 11), | |
| IF(s < 2, check = s, check + s = 11) | |
| ) | |
| ) | |
| ) | |
| // Stored Procedure, MySQL | |
| DELIMITER $$ | |
| CREATE FUNCTION is_valid_iranian_national_code(input TEXT) RETURNS BOOLEAN DETERMINISTIC BEGIN | |
| IF input NOT REGEXP '^[0-9]{10}$' THEN RETURN false; END IF; | |
| SET @i = 1, @s = 0; | |
| WHILE @i < 10 DO SET @s = @s + (11 - @i) * SUBSTR(input, @i, 1), @i = @i + 1; END WHILE; | |
| SET @s = @s % 11, @check = +SUBSTR(input, -1); | |
| RETURN IF(@s < 2, @check = @s, @check + @s = 11); | |
| END $$ | |
| DELIMITER ; |
خیلی ممنون
دوستان من قصد استفاده از بخش php برای woocommerce را دارم، لطفا بفرمایید که کد زیر چه مشکلی دارد؟
`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 : $check + $sum == 11;
}
add_filter( 'flexible_checkout_fields_custom_validation', 'wpdesk_fcf_custom_validation_CodeMelli' );
/**
- Add custom URL validation
*/
function wpdesk_fcf_custom_validation_CodeMelli( $custom_validation ) {
$custom_validation['_billing_code_melli'] = array(
'label' => 'Code Melli',
'callback' => 'isValidIranianNationalCode'
);
return $custom_validation;
}
`
سلام @mbgame اعداد تکراری نامعتبر نیست https://web.archive.org/web/20170706081048/http://www.fardanews.com/fa/news/127747/رندترین-شماره-ملی-بلای-جان-صاحبش-شد قبلاً همین regular expression را داشتیم که حذف کردم و بالای این صفحه هم این موضوع رو نوشتهام، اگر کاربر قصد دور زدن ورود عدد را داشته باشد به هر حال راهی برای دور زدن آن پیدا میکند و راهحل، اضافه کردن قانونی ناموجود نیست
thanks!
این الگوریتم ها به یک طریق دیگه ای هم گول میخورن مثل : 1666666661 3337777333 9999229999 یعنی اعداد اول و آخر مثل هم باشن و اعداد بین هم مثل هم در هر صورت کاربر یه راهی پیدا میکنه برای دور زدن!
این کد را من تست کردم و هیچ خطایی نداره
// 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);
}
دمت گرم، عالی بود😊