Giter Club home page Giter Club logo

mrz's Introduction

MRZ Generator & MRZ Checker

Description:

Machine Readable Zone generator and checker for official travel documents sizes 1, 2, 3, MRVA and MRVB (Passports, Visas, national id cards and other travel documents)

MRZ Generator and MRZ Checker are built according to International Civil Aviation Organization specifications (ICAO 9303):

Fields Distribution of Official Travel Documents:

image

Usage Generator:

TD1's (id cards):

Params:                      Case insensitive

    document_type    (str):  The first letter shall be 'I', 'A' or 'C'
    country_code     (str):  3 letters code (ISO 3166-1) or country name (in English)
    document_number  (str):  Document number
    birth_date       (str):  YYMMDD
    sex              (str):  Genre. Male: 'M', Female: 'F' or Undefined: 'X', "<" or ""
    expiry_date      (str):  YYMMDD
    nationality      (str):  3 letters code (ISO 3166-1) or country name (in English)
    surname          (str):  Holder primary identifier(s). This field will be transliterated
    given_names      (str):  Holder secondary identifier(s). This field will be transliterated
    optional_data1   (str):  Optional personal data at the discretion of the issuing State.
                             Non-mandatory field. Empty string by default
    optional_data2   (str):  Optional personal data at the discretion of the issuing State.
                             Non-mandatory field. Empty string by default
    transliteration (dict):  Transliteration dictionary for non-ascii chars. Latin based by default
    force           (bool):  Disables checks for country, nationality and document_type fields.
                             Allows to use 3-letter-codes not included in the countries dictionary
                             and to use document_type codes without restrictions.

TD2

Params:                      Case insensitive

    document_type    (str):  The first letter shall be 'I', 'A' or 'C'
    country_code     (str):  3 letters code (ISO 3166-1) or country name (in English)
    surname          (str):  Holder primary identifier(s). This field will be transliterated.
    given_names      (str):  Holder secondary identifier(s). This field will be transliterated.
    document_number  (str):  Document number.
    nationality      (str):  3 letters code (ISO 3166-1) or country name
    birth_date       (str):  YYMMDD
    sex              (str):  Genre. Male: 'M', Female: 'F' or Undefined: 'X', "<" or ""
    expiry_date      (str):  YYMMDD
    optional_data    (str):  Optional personal data at the discretion of the issuing State.
                             Non-mandatory field. Empty string by default
    transliteration (dict):  Transliteration dictionary for non-ascii chars. Latin based by default
    force           (bool):  Disables checks for country, nationality and document_type fields.
                             Allows to use 3-letter-codes not included in the countries dictionary
                             and to use document_type codes without restrictions.

TD3 (Passports)

Params:                      Case insensitive

    document_type    (str):  Normally 'P' for passport
    country_code     (str):  3 letters code (ISO 3166-1) or country name (in English)
    surname          (str):  Primary identifier(s)
    given_names      (str):  Secondary identifier(s)
    document_number  (str):  Document number
    nationality      (str):  3 letters code (ISO 3166-1) or country name
    birth_date       (str):  YYMMDD
    sex              (str):  Genre. Male: 'M', Female: 'F' or Undefined: 'X', "<" or ""
    expiry_date      (str):  YYMMDD
    optional data    (str):  Personal number. In some countries non-mandatory field. Empty string by default
    transliteration (dict):  Transliteration dictionary for non-ascii chars. Latin based by default
    force           (bool):  Disables checks for country, nationality and document_type fields.
                             Allows to use 3-letter-codes not included in the countries dictionary
                             and to use document_type codes without restrictions.

MRVA (Visas type A)

Params:                      Case insensitive

    document_type    (str):  The First letter must be 'V'
    country_code     (str):  3 letters code (ISO 3166-1) or country name (in English)
    surname          (str):  Primary identifier(s)
    given_names      (str):  Secondary identifier(s)
    document_number  (str):  Document number
    nationality      (str):  3 letters code (ISO 3166-1) or country name
    birth_date       (str):  YYMMDD
    sex              (str):  Genre. Male: 'M', Female: 'F' or Undefined: 'X', "<" or ""
    expiry_date      (str):  YYMMDD
    optional_data    (str):  Optional personal data at the discretion of the issuing State.
                             Non-mandatory field. Empty string by default.
    transliteration (dict):  Transliteration dictionary for non-ascii chars. Latin based by default
    force           (bool):  Disables checks for country, nationality and document_type fields.
                             Allows to use 3-letter-codes not included in the countries dictionary
                             and to use document_type codes without restrictions.

MRVB (Visas type B)

Params:                      Case insensitive

    document_type    (str):  The First letter must be 'V'
    country_code     (str):  3 letters code (ISO 3166-1) or country name (in English)
    surname          (str):  Primary identifier(s)
    given_names      (str):  Secondary identifier(s)
    document_number  (str):  Document number
    nationality      (str):  3 letters code (ISO 3166-1) or country name
    birth_date       (str):  YYMMDD
    sex              (str):  Genre. Male: 'M', Female: 'F' or Undefined: 'X', "<" or ""
    expiry_date      (str):  YYMMDD
    optional_data    (str):  Optional personal data at the discretion of the issuing State.
                             Non-mandatory field. Empty string by default.
    transliteration (dict):  Transliteration dictionary for non-ascii chars. Latin based by default
    force           (bool):  Disables checks for country, nationality and document_type fields.
                             Allows to use 3-letter-codes not included in the countries dictionary
                             and to use document_type codes without restrictions.
Passport generator example (ICAO9303 Specimen):

image

TD3CodeGenerator -> str:
from mrz.generator.td3 import TD3CodeGenerator

code = TD3CodeGenerator("P", "UTO", "Eriksson", "Anna María", "L898902C3", "UTO", "740812", "F", "120415","ZE184226B")

print(code)
Output:
P<UTOERIKSSON<<ANNA<MARIA<<<<<<<<<<<<<<<<<<<
L898902C36UTO7408122F1204159ZE184226B<<<<<10
Note: See other uses in mrz.generator examples folder

Usage Checker:

TD1's (id cards):

Params:

    mrz_string        (str):  MRZ string of TD1. Must be 90 uppercase characters long (3 lines)
    check_expiry     (bool):  If it's set to True, it is verified and reported as warning that the
                              document is not expired and that expiry_date is not greater than 10 years
    compute_warnings (bool):  If it's set True, warnings compute as False

TD2:

Params:

    mrz_string        (str):  MRZ string of TD2. Must be 72 characters long (uppercase) (2 lines)
    check_expiry     (bool):  If it's set to True, it is verified and reported as warning that the
                              document is not expired and that expiry_date is not greater than 10 years
    compute_warnings (bool):  If it's set True, warnings compute as False

TD3 (Passports):

Params:

    mrz_string        (str):  MRZ string of TD3. Must be 88 characters long (uppercase) (2 lines)
    check_expiry     (bool):  If it's set to True, it is verified and reported as warning that the
                              document is not expired and that expiry_date is not greater than 10 years
    compute_warnings (bool):  If it's set True, warnings compute as False

MRVA:

Params:

    mrz_string        (str):  MRZ string of Visas type A. Must be 88 characters long (uppercase) (2 lines)
    check_expiry     (bool):  If it's set to True, it is verified and reported as warning that the
                              document is not expired and that expiry_date is not greater than 10 years
    compute_warnings (bool):  If it's set True, warnings compute as False

MRVB:

Params:

    mrz_string        (str):  MRZ string of Visas type B. Must be 72 characters long (uppercase) (2 lines)
    check_expiry     (bool):  If it's set to True, it is verified and reported as warning that the
                              document is not expired and that expiry_date is not greater than 10 years
    compute_warnings (bool):  If it's set True, warnings compute as False
Id Card Checker example

image

TD1CodeChecker -> bool
from mrz.checker.td1 import TD1CodeChecker
    
check = TD1CodeChecker("I<SWE59000002<8198703142391<<<\n"
                       "8703145M1701027SWE<<<<<<<<<<<8\n"
                       "SPECIMEN<<SVEN<<<<<<<<<<<<<<<<")
result = bool(check)
print(result)
Output
True
Note: See other uses in mrz.checker examples folder
Fields extraction example (valid for td1, td2, td3 and visas)
from mrz.checker.td1 import TD1CodeChecker, get_country

td1_check = TD1CodeChecker("IDLIEID98754015<<<<<<<<<<<<<<<\n"
                           "8205122M1906224LIE<<<<<<<<<<<6\n"
                           "OSPELT<BECK<<MARISA<<<<<<<<<<<")

fields = td1_check.fields()

print(fields.name, fields.surname)
print(get_country(fields.country))
Output
MARISA OSPELT BECK
Liechtenstein
Note: See other uses in mrz.checker examples folder and this issue

Installation:

From Pypi repo (It may not be the latest version):

pip install mrz 

Cloning this repo (It may not work fine):

git clone https://github.com/Arg0s1080/mrz.git
cd mrz
sudo python3 setup.py install

Features:

  • Transliteration of special Latin characters (acutes, tildes, diaeresis, graves, circumflex, etc)
  • Arabic chars transliteration
  • Several variations of Cyrillic added: Serbian, Macedonian, Belarusian, Ukrainian and Bulgarian
  • Transliteration of modern Greek (experimental)
  • Transliteration of modern Hebrew (without vowels) (experimental)
  • Generation of the country code from its name in English (Ex.: "Netherlands" -> "NLD")
  • Name truncation detection
  • Error report, warnings report and full report in Checker.
  • Possibility that warnings compute as errors using compute_warnings keyword in Checker.
  • Possibility of disabling checks for country code, nationality and type of document, allowing to use 3-letter-codes not included in the countries dictionary and to use document_type codes without restrictions in Generator.
  • Added new checks for periods of time in Checker.
  • Visas support
  • Fields extraction in checker (name, surname, country, sex, etc) (version 0.5.0)
TODO:
  • Automatic name truncation in Generator
  • Possibility of disabling checks for country code, nationality, type of document and the others fields in Checker.
  • Add logging

IMPORTANT:

  • MRZ is a Python module to be used as library in other programs. So, its intended audience are developers. MRZ will never have a user interface nor will have CLI support. (Of course.. if someone wants, can do it) However, if someone is curious and wants to generate or check the mrz code of a passport or ID card, can modify any of the examples.

  • Right now I am very busy and have very little free time. Please, before creating an issue or consulting by email, read this issue

mrz's People

Contributors

arg0s1080 avatar asa-nisi-masa avatar ffflabs avatar t1t0n avatar ultrafunkamsterdam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mrz's Issues

mrz.generator: wrong output when primary id == ""

I discovered that something similar (comes from #1) happens in mrz.generator. When the primary identifier is not given, an incorrect output is got. For example:

from mrz.generator.td3 import TD3CodeGenerator

print(TD3CodeGenerator("P",           # Document type
                       "Utopia",      # Country
                       "",            # Surname(s)
                       "Anna María",  # Given name(s)
                       "L898902C3",   # Passport number
                       "UTO",         # Nationality
                       "740812",      # Birth date
                       "F",           # Genre
                       "120415",      # Expiry date
                       "ZE184226B"))  # Id number

This wrong output is got:

P<UTO<<ANNA<MARIA<<<<<<<<<<<<<<<<<<<<<<<<<<<
L898902C36UTO7408122F1204159ZE184226B<<<<<10

Originally posted by @Arg0s1080 in #1 (comment)

how to generate image

Thanks for great repo.
I read from tutorial, maybe I miss information for generate to image
I see issue can create basic information passport,
But i want to check by see the info in image
My question is: " how to generate passport with my background and save it to image?"
Many thanks

Bug in parsing passport with only one name

Some passports (TD3 MRZ) have only one name, like:

P<IND<<AHMADI<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
K2578285<7IND5601240F2202288<<<<<<<<<<<<<<<4

or

P<PAKZAHRA<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
DD51243520PAK8501019F27032135440067474356<98

TD3CodeChecker(value) for this input fails with this exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lib/python3.7/site-packages/mrz/checker/td3.py", line 123, in __init__
    self.result = self._all_hashes() & self._all_fields()
  File "lib/python3.7/site-packages/mrz/checker/_fields.py", line 223, in _all_fields
    self.optional_data &
  File "lib/python3.7/site-packages/mrz/checker/_fields.py", line 92, in identifier
    if check.begin_by(primary, "<") or check.begin_by(secondary, "<"):
  File "lib/python3.7/site-packages/mrz/base/string_checkers.py", line 119, in begin_by
    if string[0] != char:
IndexError: string index out of range

Code not executed after checker returns False

Hello I have a code block like this:

...
checker1 = TD3CodeChecker(...)

if bool(checker1) == True:
    ...
else:
   ...

The problem is when checker1 does not return True then all the lines below it won't run (the else statement never triggered).

Issue with georgia passports (td1)

lib incorrect calc hash value.

from mrz.generator.td1 import TD1CodeGenerator,dictionary

x1 = 'ID'
x2 = 'GEO'
x3 = '13IN30572'
x4 = '910526'
x5 = 'M'
x6 = '251221'
x7 = 'GEO'
x8 = 'MAMEDOV'
x9 = 'IUKSEL'
x10 ='10011051644'
dictionary.c
text = TD1CodeGenerator(x1,x2,x3,x4,x5,x6,x7,x8,x9,x10,force=False)
print(text)        

image

image
image

Belgian ID Cards: Issue with Document Numbers Exceeding 9 Characters in TD1

Hi there, thank you for making this library!

I have an issue with TD1, specifically scanning Belgian ID cards. If the document_number_hash digit is "<" the document will not verify.

I have checked this with 3 different Belgian ID cards and they all have "<" on index 14 of line 0.

After a ton of googling and reading specs I found an issue with the way you check document_number_hash...

Normally a document number starts at position 5 and ends at position 13 but sometimes a document number exceeds the size of it's slot and optional fields will be used, let's take a look at this example:

IDBEL123456789<1233<<<<<<<<<<<

In this case the document number check is < when we have a scenario like that we need to look at the optional numbers (1233). So when the document number check is < we need to look at the last none empty value: 3. This is the actual hash number. After that we simply verify the hash of:

Document Number: 123456789<123
Hash: 3

And this should verify as True using your verify function.

from string import ascii_uppercase, digits

def hash_string(string: str) -> str:
    """
    >>> hash_string("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
    '7'
    >>> hash_string("0123456789")
    '7'
    >>> hash_string("0123456789ABCDEF")
    '0'
    >>> hash_string("0")
    '0'
    """
    printable = digits + ascii_uppercase
    string = string.upper().replace("<", "0")
    weight = [7, 3, 1]
    summation = 0
    for i in range(len(string)):
        c = string[i]
        if c not in printable:
            raise ValueError("%s contains invalid characters" % string, c)
        summation += printable.index(c) * weight[i % 3]
    return str(summation % 10)

print(hash_string("123456789<123"))

How to pip install latest version MRZ?

Hi, the mrz checker module works great! However, I would like to pip install the latest version of mrz which includes the fields() function. How do I do so?

check return false but correctly print all the fields

There maybe a bug somewhere when I tried this with my real passport info several times. The checker returns false all the time, the report_falses return [('identifier', False)]. However I still can print out all the fields and they're all correct

Add callback to optionally "repair" fields

I'm not really sure this functionality belongs here, but as the knowledge of the MRZ internal structure is only present in this module, why not... let me know what you think!

I work with scanned MRZ, and as comes with the process, the OCR sometimes mis-reads similar characters. For example, I have seen countries read as "R0U" or a name "SZ0BO5ZLAI". And the MRZ checker correctly warns that the nationality or the identifier is not valid. However, if you could add a method repair() to the checkers

def __init__(self, mrz_code: str, check_expiry=False, compute_warnings=False, precheck=True):
        precheck and check.precheck("TD1", mrz_code, 92)
        lines = mrz_code.splitlines()
        self._document_type = self.repair('document type', lines[0][0: 2])
        self._country = self.repair('country', lines[0][2: 5])
        [...]

def repair(self, field_name: str, field_content: str):
        return field_content

that would allow me to do things like:

class MyChecker(TD1CodeChecker):
    def repair(self, name, content):
        if name in ('country', 'identifier', ...):
            # I know those can only contain alphas
            return self.replace_often_mistaken_numbers_by_alphas(content)

        if name in ('expiry date', 'birth date'):
            return self.replace_often_mistaken_alphas_by_numbers(content)

    def replace_often_mistaken_numbers_by_alphas(self, s):
        return s.replace('5', 'S').replace('1', 'I').replace('0', 'O')

This would make the checker more useful when presented with badly scanned data.

The alternative would be that I somehow preprocess the MRZ, but then I would have to re-implement the MRZ structure definition in my code too. As said above, I'm not a big fan of shoehorning that functionality into this module, but I don't see any other place that has enough knowledge of the MRZ structure.

Installation error: pip install mrz

Hi,

I can't seem to get the installation to work on MacOs Catalina

This is the error message:

pip install mrz
Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple
Collecting mrz
  Using cached https://files.pythonhosted.org/packages/85/8b/8568edf6c8725675504dcca8e4eac15ea8edb4c397f1e6d1e01d759955e9/mrz-0.6.2.tar.gz
    Complete output from command python setup.py egg_info:
    MRZ does not work on Python version < 3.4
    Your version is: 2.7.16
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-BuVQ9w/mrz/

add releases to github

There's no code release on this repository. Releases help developers get the source code of specific versions, usually when trying to look at the source code of a version from Pypi.
If possible, please match the releases here with the releases of the Pypi package.

Mrz on windows: very slow the 1st time only

Hello

mrz image.jpg > image.txt

takes about 8 - 10 seconds the 1st time for an image when that image is processed for the 1st time. The 2nd time it is a lot more faster

How do I make it faster the 1st time? Should i keep any training data locally , or any other tips please?

This is on windows 64 BIT with at least 10 GB virtual memory

Many Thanks

parser: Document number checksum on Estonian ID Cards is "<"

Estonian ID Cards seem to (sometimes? I've only had one in my data set so far!) set the document number checksum to "<", which seems to indicate no checksum.

I have not found anything in the standards for using the "<" in checksums though. Is this something you have seen before?

README before creating an issue or asking by email

Right now I'm very busy and have very little free time. Please, before creating an issue or consulting by email, follow the following steps:

For example, If i have the following sample and i want to generate MRZ Code with MRZ Generator:
aaa

  • Check that MRZ is installed (Yes, sometimes it happens xD!)

  • See distribution fields image:

fields_distribution

  • Search examples folder for a similar case:
    • [Mmmhm... this could be used!]
#!/usr/bin/python3
# -*- coding: UTF-8 -*-

from mrz.generator.td1 import *
from examples.functions.functions import open_image


print(TD1CodeGenerator(
            "ID",                                 # Document type   Normally 'I' or 'ID' for id cards
            "Serbia",                             # Country         3 letters code or country name
            "955555546",                          # Document number Special characters will be transliterated
            "680229",                             # Birth date      YYMMDD
            "F",                                  # Genre           Male: 'M', Female: 'F' or Undefined 'X'
            "130724",                             # Expiry date     YYMMDD
            "Serbia",                             # Nationality
            "ТЕСТ",                               # Surname         Special characters will be transliterated
            "МИЛИЦА",                             # Given name(s)   Special characters will be transliterated
            "2902968000000",                      # Optional data 1 empty string by default
            "",                                   # Optional data 2 empty string by default
            dictionary.cyrillic_serbian()))       # Transliteration Dictionary (latin by default)
open_image("id_cards", "Serbia.png")
  • Modify the example and run it:
from mrz.generator.td1 import TD1CodeGenerator

print(TD1CodeGenerator("CA",                 # Document type   Normally 'I' or 'ID' for id cards
                       "CAN",                # Country         3 letters code or country name
                       "9B0002562",          # Document number
                       "750625",             # Birth date      YYMMDD
                       "F",                  # Genre           Male: 'M', Female: 'F' or Undefined
                       "201029",             # Expiry date     YYMMDD
                       "MOZ",                # Nationality
                       "SPECIMEN SUMBI",     # Surname         Special characters will be transliterated
                       "GEESHNIKUT",         # Given name(s)   Special characters will be transliterated
                       "<00185978<<<<<5",    # Optional data 1
                       "<151106<01",         # Optional data 2
                       ))   # It's not necessary to transliterate .. I can ignore it
  • Lets get the output:
    • If the output is correct: No problem. FINISH
    • If the output is incorrect:
      • I check all the steps again:
        • If output is correct: Nothing happens.. I had a typo or something like that. No problem. FINISH
        • If the output is not correct: Oops! There is probably a bug or a special case. Then preferably create an issue or alternatively ask by email
    • If the output is correct but i would like it to work differentely
      • Think if it only affects my own needs or everyone's needs (or that of many)
        • If it only affects me: Modify the code or write a class that overrides originals. Tip: See what's done in special cases folder (Note: Due a desing problem the name of the class must start with TD1, TD2, TD3 or Passport and must end with CodeGenerator or CodeChecker)
        • If it benefits to everyone (or many): Open a new issue requesting a enhancement or make a Pull Request

I understand that errors happen (I make a lot everyday), but please... I demand a minimum of effort before asking.

Thank you very much and best regards

No module named 'examples.functions'

When running on Linux Manjaro, I get the error:

File "/home/user/mrz/examples/mrz_generator_samples/passport_uto.py", line 5, in
from examples.functions.functions import open_image
ModuleNotFoundError: No module named 'examples.functions'

Run command: python passport_uto.py
How i can fix this error?

Checker: Fields Extraction Support

Several people have asked me by email how they get the fields (names, surnames, nationality, type of document, etc. strings) without access to a protected member of the class. Therefore I have created the fields() method for td1, td2, td3, mrva and mrvb.

For example:

from mrz.checker.td1 import TD1CodeChecker, get_country

mrz_td1 = ("IDD<<ID98754015<<<<<<<<<<<<<<<\n" 
           "8205122M1906224D<<<<<<<<<<<<<6\n" 
           "SCHNEIDER<WEBER<<NORBERT<<<<<<")

td1_check = TD1CodeChecker(mrz_td1)

To get identifiers, country, and date of birth....

Before (accessing to protected members of the class):

print(td1_check._identifier)
print(td1_check._country)
print(td1_check._birth_date)
Output:
SCHNEIDER<WEBER<<NORBERT<<<<<<
D<<
820512

Now:

fields() method returns a namedtuple with all fields strings:

td1_check.fields()
Returns:
fields(document_type='ID', country='D', document_number='ID9875401', document_number_hash='5', optional_data='', birth_date='820512', birth_date_hash='2', sex='M', expiry_date='190622', expiry_date_hash='4', nationality='D', optional_data_2='', final_hash='6', surname='SCHNEIDER WEBER', name='NORBERT')

So, to get given names, surnames and birth date:

fields = td1_check.fields()
print(fields.surname)
print(fields.name)
print(get_country(fields.country))
print(fields.birth_date)
Output:
SCHNEIDER WEBER
NORBERT
Germany
820512

Available fields

id cards and others td1's:

surname, name, country, nationality, birth_date, expiry_date, sex, document_type,
document_number, optional_data, birth_date_hash, expiry_date_hash, document_number_hash,
 optional_data_2 and final_hash

td2's:

surname, name, country, nationality, birth_date, expiry_date, sex, document_type,
document_number, optional_data, birth_date_hash, expiry_date_hash, document_number_hash
and final_hash

Passports and other td3's:

surname, name, country, nationality, birth_date, expiry_date, sex, document_type,
document_number, optional_data, birth_date_hash, expiry_date_hash, document_number_hash,
optional_data_hash and final_hash

Any Visa (mrva & mrvb)

surname, name, country, nationality, birth_date, expiry_date, sex, document_type,
document_number, optional_data, birth_date_hash, expiry_date_hash and document_number_hash

Empty optional data field and empty optional data hash in TD3 format will result in a invalid hash in the TD3CodeChecker

Hi!

I have a Swiss passport with a MRZ in the TD3 format. On this document no optional data is used, hence its MRZ value is <<<<<<<<<<<<<<. The corresponding optional data hash is <.

I would expect that this would result in a valid MRZ readout, but this seems not the case. The empty values are not recognized as a valid value-hash pair: hash_is_ok("<<<<<<<<<<<<<<", "<") returns False. This in turn causes TD3CodeChecker(mrz) to cast to a False boolean.

NLD ID optional data hash

The netherlands ID (TD1) has optional data. at line 1 position 30 there is a hash number. Is there any chance for me to change the script of TD1 for another hash at line 1 pos 30?

Two letter country code

I believe, there is an error in TD1CodeChecker, atlest for some IDs.

Two letter country codes and nationality codes do not pass the check, while three letter country codes do.

There should also be a possibility of two letter country codes added to check, because some IDs have two letter country and nationality code.

Tutorial how to use?

Is there any tutorial how to use this? Im new at this and don’t know what to do. I already have python and used pip install MRZ but I don’t know what else to do. I need to generate german id mrz

Does code take into account some (US) passports have 5-6 check digits at the end of line 2?

I have not tried your application yet, but I have investigated the isse for some time, and if you use the documents you refer to as te background for generatoing MRZ code ("Specifications for Machine Readable Passports (MRPs)"), then it does not seem to take into account that there can be more than 2 digits a the end of line 2.

Every US passports I have seen lately look something like this in line 2: ".......123456789<23456" and not like "....123456789<<<32"
I have not been able to find any documentation for this?

Have you solved this issue?

/Christian

Germany is denoted by 1 letter

In the list of countries (mrz/base/countries), all countries are denoted with 3 letters except Germany which is denoted with the single letter D while acording to: ISO_3166-1 it should be DEU

Undefined variable 's' in Precheck method

Hello,

I ran into the following bug when calling the precheck method:

raise LengthError(cause=len(s), document=document_description, length=length)
NameError: name 's' is not defined

Having a look at precheck method in string_checkers.py in 0.5.8 I observe the following:


def precheck(document_description: str, string: str, length: int):
    s = string.replace("\n", "")
    if _is_string(_check_upper(string)) and len(s) != length:
        raise LengthError(cause=len(s), document=document_description, length=length)
    if not is_printable(s):
        raise FieldError("%s contains invalid characters" % document_description, s)

Having a look at precheck method in string_checkers.py in 0.6.1 I observe the following:

def precheck(document_description: str, string: str, length: int):
    if check_string(_check_upper(string)) and len(string) != length:
        raise LengthError(cause=len(s), document=document_description, length=length)
    if not is_printable(string, "\n"):
        raise FieldError("%s contains invalid characters" % document_description, s)

Since the removal of s = string.replace("\n", "") there is no defined variable s anymore. Both the LengthError and FieldError reference to this. I believe it should be string instead of s now.

Nonspecified sex should be < instead of X

According to page 14 of this ICAO document: https://www.icao.int/publications/Documents/9303_p5_cons_en.pdf

Sex in the MRZ can be: M for male,F for female, and < for nonspecified.
However, the generator puts in a X for nonspecified instead of a <.

This is correct for the VIZ as can be seen in the same document at page 11.
But not for the MRZ.

The document refers to TD1 but it also aplies for the other document types:

Optional data hash is checked even if optional data is empty

While working with austrian ID cards and passports, I noticed that many of them fail the "optional data hash" check. For example (name and ID number redacted):

P<AUTPL***<<**********<<<<<<<<<<<<<<<<<<<<<<
U******9<4AUT9211041F2505060<<<<<<<<<<<<<<<2
type TD3

--> False 
fields(surname='PL***', name='*********', country='AUT', nationality='AUT', birth_date='921104', 
expiry_date='250506', sex='F', document_type='P', document_number='U******9', optional_data='', 
birth_date_hash='1', expiry_date_hash='0', document_number_hash='4', optional_data_hash='<', 
final_hash='2')

[('final hash', True), ('document number hash', True), ('birth date hash', True), ('expiry date hash', True),
('optional data hash', False), ('document type format', True), ('valid country code', True), 
('valid nationality code', True), ('birth date', True), ('expiry date', True), ('valid genre format', True), 
('identifier', True), ('document number format', True)]

and

P<AUTK******<<*********<<<<<<<<<<<<<<<<<<<<<
U******3<0AUT8402183M2610209<<<<<<<<<<<<<<<0
type TD3

--> False 
fields(surname='K******', name='*********', country='AUT', nationality='AUT', birth_date='840218',
expiry_date='261020', sex='M', document_type='P', document_number='U******3', optional_data='',
birth_date_hash='3', expiry_date_hash='9', document_number_hash='0', optional_data_hash='<', 
final_hash='0')

[('final hash', True), ('document number hash', True), ('birth date hash', True), ('expiry date hash', True),
('optional data hash', False), ('document type format', True), ('valid country code', True), 
('valid nationality code', True), ('birth date', True), ('expiry date', True), ('valid genre format', True), 
('identifier', True), ('document number format', True)]

I suppose, that should not be checked if there is no optional_data and/or if the optional_data_hash is '<'?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.