Проверка удостоверения личности устроена сложнее, чем проверка банковского или товарного номера, потому что здесь нет ни одного общего стандарта, который связывал бы все страны. Ниже разберём, почему единая формула для документов разных стран невозможна в принципе, как три группы стран различаются по объёму опубликованных правил, что делать, когда одна строка подходит сразу нескольким системам, и почему длина и состав знаков — это только начало разговора, а не его итог.
Почему документы разных стран нельзя проверять одной формулой?
Причина проста: нет органа, который устанавливал бы общие правила нумерации документов для всего мира. Каждая страна ведёт свою систему регистрации, сама решает, из чего состоит номер, сколько в нём знаков, есть ли у него контрольная цифра и публикуется ли правило её вычисления.
Такая свобода даёт каждой стране удобство, но лишает нас универсального решения. Строка, пришедшая в форму, сама по себе почти ничего не сообщает о том, по чьим правилам её читать. Две буквы в начале или определённая длина могут намекнуть на страну, но намёк — не доказательство, и строить на нём проверку нельзя.
Отсюда первое практическое правило: страну нужно знать из контекста, а не вычислять из номера. Если пользователь выбрал страну в форме, читайте номер по её правилам. Если не выбрал — честно покажите, что без этого проверка формата теряет смысл, и предложите выбор.
Три группы стран по объёму опубликованных правил
Различия удобно свести к трём группам, и именно эти три группы определяют, какой ответ вы имеете право дать пользователю.
| Группа | Что опубликовано | Что можно подтвердить | Чего подтвердить нельзя |
|---|---|---|---|
| Первая | алгоритм контрольной цифры | согласованность всей строки | существование и владельца документа |
| Вторая | только формат: длина и состав знаков | что строка похожа на номер нужного вида | ничего сверх этого |
| Третья | правила описаны неполно | почти ничего, кроме общего вида | ничего сверх общего вида |
Первая группа даёт самый богатый ответ, но и он ограничен. Правило вычисления открыто, а значит, согласованную строку может собрать кто угодно. Поэтому первая группа позволяет сказать «запись непротиворечива», но не «документ настоящий».
Вторая группа — самая распространённая и самая неудобная для проектирования интерфейса. Формат подтверждён, но о значении строки не известно ничего. Здесь важно не поддаться соблазну и не написать «действителен»: это слово обещает ровно то, чего проверить не удалось. Отдельный разбор этого случая есть в материале про номера без контрольной цифры.
Третья группа — это признание границы возможного. Правило или не опубликовано, или опубликовано частично, и тогда честный ответ звучит как «у нас нет правила для этой строки». Это не приговор документу, а описание нашей осведомлённости.
Может ли один номер подойти нескольким странам?
Представим, что форма принимает номер без выбора страны. Строка из известного количества цифр может подойти сразу нескольким системам: одна страна допускает такую длину, другая использует тот же диапазон, а третья совпадает и по длине, и по арифметике контрольной цифры.
Такое совпадение не редкость, а норма, потому что диапазоны длин у разных систем пересекаются, а семейств алгоритмов в мире всего несколько. Значит, у проверки может быть не один правильный ответ, а несколько равноправных.
Что делать в этой ситуации? Не выбирать. Правильное поведение — перечислить все системы, которым строка удовлетворяет, и по каждой дать отдельный вывод. Пользователь увидит, что его строка подходит нескольким вариантам, и сам решит, какой из них имелся в виду. Инструмент, который молча выбирает одну страну, уверенно ошибается в остальных случаях.
Этот же принцип защищает и от обратной крайности. Соблазнительно отклонить строку, сославшись на то, что она подошла нескольким системам, — но неоднозначность не является признаком ошибки. Строка может быть совершенно корректным документом, просто у нас недостаточно контекста, чтобы сказать, каким именно.
Длина и состав знаков — это только начало
Самый частый дефект форм — считать проверку длины полноценной проверкой. Логика обычно такая: раз число знаков совпало, значит номер правильный. На деле совпадение длины доказывает лишь одно: в строке примерно столько знаков, сколько бывает в номерах этого вида.
Проблема в том, что длина — самая слабая из всех характеристик. Она совпадает у множества систем, не мешает опечатке внутри строки и ничего не говорит о том, осмысленны ли знаки. Опечатка в середине номера при сохранении длины пройдёт такую проверку молча.
Практический вывод: определяйте, что именно вы проверили, и говорите об этом прямо. «Число знаков соответствует ожидаемому» — честное сообщение. «Номер действителен» — нет. Между этими формулировками лежит разница между фильтром опечаток и утверждением о реальности, и смешивать их не стоит. Природа этой разницы разобрана в разборе устройства проверки номера.
Как сделать правила стран заменяемыми данными
Если каждый национальный формат зашит условиями внутри логики, система становится хрупкой: изменение правил одной страны требует правки кода, а тестирование превращается в перебор веток. Гораздо устойчивее подход, при котором правила живут отдельно от процедуры проверки.
Что стоит вынести в данные. Код страны и признак того, применяется ли правило. Допустимую длину или набор допустимых длин. Разрешённый состав знаков. Ссылку на алгоритм контрольной цифры из семейства, если он опубликован. Отдельный признак для тех случаев, когда алгоритма нет: тогда поведение системы отличается, а не «подставляется ближайший похожий алгоритм».
Почему последний пункт критичен. Если для системы без опубликованного алгоритма подставить похожее правило, вы начнёте отвергать корректные документы. Ложное отклонение обходится дороже, чем отсутствие проверки: пользователь не может обойти вашу форму и уходит.
Второе следствие работы с данными — версионирование. Правила меняются, и когда-нибудь понадобится объяснить, почему год назад строка была принята, а сегодня отклонена. Если правила хранятся с отметкой о версии, такой вопрос решается за минуту. Если они зашиты в код, остаётся только гадать.
Что важно объяснить пользователю при отказе
Формулировка отказа важнее, чем кажется. Отказ, который ничего не объясняет, заставляет пользователя менять корректные данные наугад.
Полезно различать четыре ситуации и говорить о них по-разному. Первая: строка не подходит по составу знаков — тут есть что исправить. Вторая: не совпала длина — тоже конкретное действие. Третья: формат в порядке, но контрольная цифра не сошлась — скорее всего, опечатка, и стоит перечитать номер. Четвёртая: правила для этой системы у нас нет вовсе — и это не ошибка пользователя.
Последний случай заслуживает отдельной настойчивости. Когда у системы нет правила, правильный ответ — сообщить об этом, а не выдавать отказ в форме утверждения о номере. Пользователь не должен переделывать корректный документ из-за того, что ваша таблица правил неполна.
Что делать дальше
Начните с инвентаризации: выпишите страны, с которыми работает ваша форма, и для каждой зафиксируйте, что именно опубликовано — алгоритм, только формат или ничего внятного. Скорее всего, окажется, что для части стран у вас сейчас стоит проверка, которой не существует.
Затем откройте инструмент проверки и посмотрите, как он перечисляет возможные системы для одной и той же строки и как формулирует вывод, когда правила нет. Сравните эти формулировки со своими — расхождение подскажет, где ваше сообщение обещает больше, чем вы можете подтвердить, а где вы напрасно отклоняете корректный документ. Отдельный разбор двух бразильских налоговых номеров — проверка CPF CNPJ — хорошо показывает, как две родственные системы уживаются рядом и почему их правила всё равно нельзя свести к одному.