Skip to content

Instantly share code, notes, and snippets.

@faruktoptas
Last active November 5, 2022 14:08
Show Gist options
  • Save faruktoptas/0d84878d1ff1f61ba1ee05af2c3af7a7 to your computer and use it in GitHub Desktop.
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
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