Last active
November 5, 2022 14:08
-
-
Save faruktoptas/0d84878d1ff1f61ba1ee05af2c3af7a7 to your computer and use it in GitHub Desktop.
MRZ validate algorithm for passports. http://en.wikipedia.org/wiki/Machine-readable_passport
This file contains 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
object MrzValidator { | |
private val COEFFICIENTS = listOf(7, 3, 1) | |
private const val EMPTY = '<' | |
/** | |
* Samples: | |
* - Document number: isValid("D123456785", 0, 9) actual document number is "D12345678" check character is "5" | |
* - Date: isValid("7903063", 0, 6)) actual date is "790306" check character is "3" | |
*/ | |
fun isValid(str: String, start: Int, end: Int): Boolean { | |
if (str.length > end && end > start) { | |
val data = str.substring(start, end) | |
val check = str.substring(end, end + 1) | |
return try { | |
val calculatedCheck = calculateCheck(data) | |
println("Data: $data check character: $check calculated check character: $calculatedCheck") | |
calculatedCheck == check.toInt() | |
} catch (e: Exception) { | |
false | |
} | |
} | |
return false | |
} | |
private fun calculateCheck(str: String): Int { | |
var total = 0 | |
str.forEachIndexed { index, c -> | |
total += getCharValue(c) * COEFFICIENTS[index % COEFFICIENTS.size] | |
} | |
return total % 10 | |
} | |
private fun getCharValue(char: Char): Int { | |
return when (char) { | |
EMPTY -> 0 | |
in '0'..'9' -> char - '0' | |
in 'A'..'Z' -> char - 'A' + 10 | |
else -> throw RuntimeException("Not valid character") | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment