Um passaporte cuja zona de leitura mecânica passa em todos os dígitos verificadores parece confiável. A conta fecha, o validador devolve true cinco vezes e o fluxo de cadastro segue em frente. Vale ser preciso sobre o que esse true significa, porque a promessa é menor do que parece.

Este guia é para desenvolvedores que constroem fluxos de KYC e de onboarding. Ele separa as verificações de triagem mais comuns entre o que os dígitos verificadores da MRZ detectam, o que eles não conseguem detectar e qual outra verificação cobre cada lacuna. Todas as zonas abaixo são o próprio espécime da ICAO, Anna Maria Eriksson de "Utopia", ou uma variante dele inventada para este post. Nenhum documento real aparece.

Este é o blog do doc.cheap, uma API de OCR para passaportes e documentos de identidade. Nada do que vem a seguir depende dela.

Para que servem os dígitos

A MRZ é o bloco de letras maiúsculas, dígitos e caracteres de preenchimento < na parte de baixo da página de dados do passaporte ou no verso de uma carteira de identidade. O ICAO Doc 9303 dá a ela dígitos verificadores: um para o número do documento, um para a data de nascimento e um para a data de validade, um para o número pessoal opcional dos passaportes e um dígito composto sobre quase toda a linha inferior.

Cada dígito é uma soma ponderada. Cada caractere vira um número (0–9 valem eles mesmos, A = 10 até Z = 35, < = 0), os números são multiplicados pelos pesos 7, 3, 1, que se repetem, e a soma módulo 10 é o dígito. Como funcionam os dígitos verificadores da MRZ mostra o passo a passo com um validador que você pode colar no seu código.

Os dígitos foram criados para pegar erros de leitura. Nunca tiveram a função de detectar fraude, e tudo o que vem a seguir decorre disso.

O que um dígito verificador detecta

Um único dígito errado. Como 7, 3 e 1 não têm fator em comum com 10, trocar qualquer dígito de um campo por outro dígito sempre muda a soma módulo 10. Um 3 lido como 8, um 5 lido como 6: o dígito do campo deixa de bater, e o composto também.

A maioria das trocas entre dois vizinhos. Se dois caracteres adjacentes trocam de lugar, a soma muda pela diferença entre eles multiplicada pela diferença dos seus pesos (4, 2 ou 6). Isso só é múltiplo de 10 quando os dois valores diferem por um múltiplo de 5. Assim, 98 digitado como 89 é detectado, enquanto 16 digitado como 61 passa despercebido, assim como 05 digitado como 50.

Danos, reflexos e redigitação. É aqui que os dígitos mostram seu valor. Uma dobra sobre um caractere, um reflexo na laminação, uma pessoa redigitando uma zona à mão: é isso que causa a maior parte dos dados de MRZ ruins, e um dígito que falha é o sinal barato de que um campo foi lido errado. A resposta certa é uma nova foto, não uma rejeição.

Onde a aritmética não enxerga

Os dígitos têm pontos cegos mesmo para erros honestos, e um fluxo de triagem deveria conhecê-los.

Uma letra lida como um caractere cujo valor difere em 10, 20 ou 30. Pegue o número de documento do espécime, L898902C3, cujo dígito verificador é 6. Troque o C (valor 12) por um 2 (valor 2): a soma cai 10 × 3 = 30, de 316 para 286, e o dígito continua sendo 6. O composto, que cobre os mesmos caracteres com o mesmo peso, também continua passando. Pares como B e 1, ou C e 2, podem se substituir sem fazer barulho.

Campos que nenhum dígito cobre. O nome, o Estado emissor, a nacionalidade e o sexo ficam fora de todos os dígitos de campo, e o composto também pula a nacionalidade e o sexo. Um nome lido errado passa em silêncio; só uma comparação com a página impressa o revela.

O que ela não consegue detectar de jeito nenhum

Tudo nesta seção passa nos dígitos verificadores da MRZ, por construção.

Um documento falsificado com uma zona coerente. O algoritmo é público e cabe em vinte linhas de código. Quem produz um documento falso calcula os dígitos corretamente, porque um dígito errado é o único erro que qualquer leitor pega de graça. Uma zona que passa diz que a zona foi lida corretamente. Não diz nada sobre o documento ser autêntico.

Dados copiados de uma pessoa real. Uma zona montada com o nome, a data de nascimento e o número de documento reais de outra pessoa tem dígitos válidos, porque os dados são reais. Se a pessoa diante da câmera é essa pessoa é outra questão: uma comparação facial com a foto do documento, uma prova de vida ou uma consulta à lista de documentos perdidos e roubados de um emissor, quando você tem acesso a uma.

Um documento vencido. A data de validade 120415 passa no seu dígito verificador, e é 15 de abril de 2012. Validade é uma norma sobre datas, não um checksum: compare a data com a de hoje. Lembre que YYMMDD não tem século, então decida pelo contexto; o formato de data YYMMDD explica como. A calculadora de dígitos verificadores da MRZ deste site marca uma data de validade no passado como vencida ao lado dos dígitos, para você ver as duas respostas lado a lado.

Uma foto substituída. A MRZ não traz imagem nem hash de imagem. Uma foto trocada na página de dados deixa a zona intacta.

Um chip clonado ou adulterado. Num passaporte com chip, os grupos de dados são assinados pelo Estado emissor, e verificar essa assinatura (Passive Authentication, ICAO Doc 9303 Parte 11) é como se sabe que os dados vieram do emissor. Isso exige uma leitura por NFC e os certificados do emissor. Uma foto da página, por melhor que seja, não responde a essa pergunta. A MRZ só fornece a chave de acesso usada para abrir o chip.

A verificação que todo mundo pula: a zona contra a página

Um documento diz quase tudo duas vezes: uma na MRZ e outra na zona de inspeção visual (VIZ), a página impressa que uma pessoa lê. As duas foram produzidas juntas por um mesmo emissor, então, num documento autêntico e sem danos, elas concordam.

Isso torna uma divergência mais interessante do que um dígito que falha. Um dígito que falha costuma significar uma foto ruim. Dígitos que passam ao lado de um sobrenome, uma data de nascimento ou um número de documento impressos que dizem outra coisa significam que um dos lados foi lido errado ou alterado depois da impressão. Em qualquer dos casos, é um documento para uma pessoa olhar.

A comparação precisa ser feita de propósito. Leia as duas zonas, normalize os valores impressos (datas no mesmo formato, nomes reduzidos a letras maiúsculas puras) e compare campo a campo. Leve em conta a transliteração: um Müller impresso pode ser MUELLER ou MULLER na zona, dependendo do emissor. A página de formatos de MRZ mostra quais campos cada formato traz e, portanto, quais podem ser comparados.

Uma ordem de triagem que se sustenta

  1. Formato. A quantidade e o comprimento das linhas definem TD1, TD2 ou TD3. Um formato errado é uma leitura ruim.
  2. Dígitos verificadores. Uma falha significa tirar outra foto, não rejeitar.
  3. Zona contra página. Uma divergência com dígitos que passam vai para uma pessoa.
  4. Datas. Validade contra a data de hoje; data de nascimento contra as suas normas de idade.
  5. Identidade. Comparação facial e prova de vida contra a foto do documento.
  6. Autenticidade. Verificação do chip por NFC, ou elementos de segurança físicos verificados por um serviço feito para isso.

Os passos 1 a 4 são baratos e rodam em qualquer imagem. Os passos 5 e 6 são produtos à parte, e nenhuma quantidade de aritmética de MRZ os substitui.

Onde o doc.cheap se encaixa

A API de OCR de passaportes do doc.cheap cobre os passos 1 a 4 e é honesta sobre o resto. A resposta traz mrz.status: passed, failed ou absent. Em failed, mrz.reason diz o que não bateu, seja um dígito (Check digit failed for: document number), seja uma divergência com a página impressa (MRZ does not match the visual zone for: surname), porque as duas zonas são lidas e comparadas por padrão. A zona em si volta literalmente em mrz.lines e mrz.text, para você recalcular os dígitos no seu próprio código. document.expiry_date, document.is_expired e document.days_remaining respondem ao passo 4.

É um serviço de reconhecimento, não de verificação. O bloco authenticity traz not_checked em vez de sugerir uma aprovação, e as verificações de foto e de chip ficam com as ferramentas feitas para elas. Para testar uma zona sem escrever código, cole-a na calculadora de dígitos verificadores da MRZ; ela roda no navegador e mostra cada dígito calculado ao lado do impresso. Se você está escolhendo um serviço hospedado, a comparação de APIs de OCR de passaporte coloca os preços publicados lado a lado.

Uma pergunta para você: qual dessas lacunas o seu fluxo de onboarding já encontrou na prática? Conte para nós nos comentários abaixo.