Alireza Noorali
Alireza Noorali

Reputation: 3265

How to validate Iranian National Code (Melli Code or Code Melli) in android

I need a method to validate the Melli Code (National Code or Code Melli) of Iranian people.

I Know it has a formula.

Upvotes: 18

Views: 9752

Answers (9)

Mahan
Mahan

Reputation: 211

For Flutter Developer:

String? personalId(String? value) {
  if (value == null || value == '' || value!.length != 10) {
    return 'کدملی وارد شده معتبر نمیباشد';
  }

  // Check if all the numbers are the same
  bool areAllNumbersSame = true;
  for (int i = 1; i < 10; i++) {
    if (value[0] != value[i]) {
      areAllNumbersSame = false;
      break;
    }
  }
  if (areAllNumbersSame) {
    return 'کدملی وارد شده معتبر نمیباشد'; // Fake National Code
  }

  int sum = 0;

  for (int i = 0; i < 9; i++) {
    sum += int.parse(value[i]) * (10 - i);
  }

  int lastDigit;
  final int divideRemaining = sum % 11;

  if (divideRemaining < 2) {
    lastDigit = divideRemaining;
  } else {
    lastDigit = 11 - divideRemaining;
  }

  if (int.parse(value[9]) == lastDigit) {
    return null; // Valid National Code
  } else {
    return 'کدملی صحیح نیست'; // Invalid National Code
  }
}

Upvotes: 0

milad_vayani
milad_vayani

Reputation: 440

JAVA:

public class NationalCodeValidator {

public static void validateNationalCode(String nc) throws Exception {
    // Check if the length of the national code is not 10
    if (nc.length() != 10) {
        throw new Exception("Invalid National Code");
    }

    // Check if the national code is numeric
    try {
        Long.parseLong(nc);
    } catch (NumberFormatException e) {
        throw new Exception("Invalid National Code");
    }

    // Check for national codes that should not be valid
    for (int i = 0; i < 10; i++) {
        String notNational = String.valueOf(i).repeat(10);
        if (nc.equals(notNational)) {
            throw new Exception("Invalid National Code");
        }
    }

    // Calculate the check digit
    int total = 0;
    for (int i = 0; i < 9; i++) {
        int digit = Integer.parseInt(nc.substring(i, i + 1));
        total += digit * (10 - i);
    }

    int remainder = total % 11;
    int checkDigit = Integer.parseInt(nc.substring(9));

    if (remainder < 2) {
        if (checkDigit != remainder) {
            throw new Exception("Invalid National Code");
        }
    } else {
        if (checkDigit != 11 - remainder) {
            throw new Exception("Invalid National Code");
        }
    }
}

// Example usage
public static void main(String[] args) {
    try {
        validateNationalCode("1234567891");
        System.out.println("Valid National Code");
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
}
}

PYTHON:

def validate_national_code(nc: str):
    """
    algorithm for check that national number is right
    """
    if len(nc) != 10:
        raise ValueError("Invalid National Code")
    try:
        int(nc)
    except (TypeError, ValueError):
        raise ValueError("Invalid National Code")
    not_national = list()
    for i in range(0, 10):
        not_national.append(str(i) * 10)
    if nc in not_national:
        raise ValueError("Invalid National Code")
    total = 0
    nc_p = nc[:9]
    i = 0
    for c in nc_p:
        total = total + int(c) * (10 - i)
        i = i + 1
    rem = total % 11
    if rem < 2:
        if int(nc[9]) != rem:
            raise ValueError("Invalid National Code")
    else:
        if int(nc[9]) != 11 - rem:
            raise ValueError("Invalid National Code")

Upvotes: 0

Ebrahim Byagowi
Ebrahim Byagowi

Reputation: 11258

I have different versions of it here and the following is its Kotlin one,

fun isValidIranianNationalCode(input: String) = input.takeIf { it.length == 10 }
    ?.mapNotNull(Char::digitToIntOrNull)?.takeIf { it.size == 10 }?.let {
        val check = it[9]
        val sum = it.slice(0..8).mapIndexed { i, x -> x * (10 - i) }.sum() % 11
        if (sum < 2) check == sum else check + sum == 11
    } ?: false

Upvotes: 4

Alireza Noorali
Alireza Noorali

Reputation: 3265

This method validates the Iranian people's National code.

public boolean validateMelliCode(String melliCode) {

    String[] identicalDigits = {"0000000000", "1111111111", "2222222222", "3333333333", "4444444444", "5555555555", "6666666666", "7777777777", "8888888888", "9999999999"};

    if (melliCode.trim().isEmpty()) {
        Toast.makeText(getApplicationContext(), "National Code is empty", Toast.LENGTH_LONG).show();
        return false; // National Code is empty
    } else if (melliCode.length() != 10) {
        Toast.makeText(getApplicationContext(), "National Code must be exactly 10 digits", Toast.LENGTH_LONG).show();
        return false; // National Code is less or more than 10 digits
    } else if (Arrays.asList(identicalDigits).contains(melliCode)) {
        Toast.makeText(getApplicationContext(), "MelliCode is not valid (Fake MelliCode)", Toast.LENGTH_LONG).show();
        return false; // Fake National Code
    } else {
        int sum = 0;

        for (int i = 0; i < 9; i++) {
            sum += Character.getNumericValue(melliCode.charAt(i)) * (10 - i);
        }

        int lastDigit;
        int divideRemaining = sum % 11;

        if (divideRemaining < 2) {
            lastDigit = divideRemaining;
        } else {
            lastDigit = 11 - (divideRemaining);
        }

        if (Character.getNumericValue(melliCode.charAt(9)) == lastDigit) {
            Toast.makeText(getApplicationContext(), "MelliCode is valid", Toast.LENGTH_LONG).show();
            return true;
        } else {
            Toast.makeText(getApplicationContext(), "MelliCode is not valid", Toast.LENGTH_LONG).show();
            return false; // Invalid MelliCode
        }
    }
}

UPDATE

This authentic news agency said there is a man who has "1111111111" national code, so we have to accept the national codes composed of repetitive digits. So we don't need this Array:

String[] identicalDigits = {"0000000000", "1111111111", "2222222222", "3333333333", "4444444444", "5555555555", "6666666666", "7777777777", "8888888888", "9999999999"};

and also we don't need this part of condition:

else if (Arrays.asList(identicalDigits).contains(melliCode)) {
        Toast.makeText(getApplicationContext(), "MelliCode is not valid (Fake MelliCode)", Toast.LENGTH_LONG).show();
        return false; // Fake National Code
    } 

Good Luck!

Upvotes: 23

Mohammad Moradi
Mohammad Moradi

Reputation: 41

You can validate your national code like this:

Updated

public static boolean isValidNationalCode(String nationalCode)
{
      if (!nationalCode.matches("^\\d{10}$"))
          return false;

      int sum = 0;

      for (int i = 0; i < 9; i++)
      {
          sum += Character.getNumericValue(nationalCode.charAt(i)) * (10 - i);
      }

      int lastDigit = Integer.parseInt(String.valueOf(nationalCode.charAt(9)));
      int divideRemaining = sum % 11;

      return ((divideRemaining < 2 && lastDigit == divideRemaining) ||   (divideRemaining >= 2 && (11 - divideRemaining) == lastDigit ));
}

Upvotes: 4

Ehsan Kamali
Ehsan Kamali

Reputation: 11

First, use the System.Text.RegularExpressions class and then use this script:.

#region NationalCode Check

public bool NationalCodeCheck(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);
}

#endregion

Upvotes: 1

Iman Marashi
Iman Marashi

Reputation: 5753

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);
}

Upvotes: 1

Amir Rezvani
Amir Rezvani

Reputation: 1504

For Javascript Developers:

const checkCodeMeli = code => {
    console.log("an");
    var L = code.length;

    if (L < 8 || parseInt(code, 10) === 0) return false;
    code = ("0000" + code).substr(L + 4 - 10);
    if (parseInt(code.substr(3, 6), 10) === 0) return false;
    var c = parseInt(code.substr(9, 1), 10);
    var s = 0;
    for (var i = 0; i < 9; i++) {
      s += parseInt(code.substr(i, 1), 10) * (10 - i);
    }
    s = s % 11;
    return (s < 2 && c === s) || (s >= 2 && c === 11 - s);
  };

Upvotes: 1

Arash
Arash

Reputation: 944

Good job Alireza, Here is my code which is very similar to yours.

‍‍‍

private boolean isValidNationalCode(String nationalCode) {
    if (nationalCode.length() != 10) {
      return false;
    } else {
      //Check for equal numbers
      String[] allDigitEqual = {"0000000000", "1111111111", "2222222222", "3333333333",
          "4444444444", "5555555555", "6666666666", "7777777777", "8888888888", "9999999999"};
      if (Arrays.asList(allDigitEqual).contains(nationalCode)) {
        return false;
      } else {
        int sum = 0;
        int lenght = 10;
        for (int i = 0; i < lenght - 1; i++) {
          sum += Integer.parseInt(String.valueOf(nationalCode.charAt(i))) * (lenght - i);
        }

        int r = Integer.parseInt(String.valueOf(nationalCode.charAt(9)));

        int c = sum % 11;

        return (((c < 2) && (r == c)) || ((c >= 2) && ((11 - c) == r)));
      }

    }
  }

Upvotes: 6

Related Questions