Проверка делимости

Проверка делимости валидационными средствами в JavaScript обычно реализуется на уровне пользовательских правил, поскольку стандартная библиотека Validator.js ориентирована на проверку форматов строковых данных (email, URL, числовые строки, длины и диапазоны), а не на математические операции. Тем не менее, механизм расширения позволяет встроить любые арифметические условия, включая проверку делимости чисел.

Validator.js работает преимущественно со строками. Это принципиально важно, поскольку входные данные часто поступают из HTTP-запросов, форм HTML или JSON, где числа представлены текстом.

Основные методы предварительной проверки:

  • isNumeric(value) — проверка, что строка содержит число
  • isInt(value) — проверка, что значение является целым числом
  • toInt(value) — преобразование строки в целое число (вспомогательная логика вне ядра библиотеки)

Пример базовой подготовки данных:

const validator = require('validator');

const value = "42";

if (validator.isNumeric(value)) {
  const number = parseInt(value, 10);
}

Базовая проверка делимости через пользовательскую функцию

Проверка делимости сводится к математической операции остатка от деления. Условие делимости формулируется как:

число делится на N, если остаток от деления равен 0

Реализация пользовательского валидатора

const validator = require('validator');

function isDivisible(value, divisor) {
  if (!validator.isInt(value)) {
    return false;
  }

  const number = parseInt(value, 10);

  if (divisor === 0) {
    return false;
  }

  return number % divisor === 0;
}

Функция учитывает два ключевых аспекта:

  • проверку корректности входного значения как целого числа
  • защиту от деления на ноль

Интеграция с расширяемыми правилами валидации

Validator.js позволяет формировать слой абстракции поверх стандартных проверок. Обычно это реализуется через собственные модули валидации.

Пример композиции правил:

function validateUserInput(value) {
  return validator.isNumeric(value) && isDivisible(value, 5);
}

В данном случае проверяется, что значение:

  • является числом
  • кратно 5

Проверка делимости для больших чисел

Стандартный Number в JavaScript имеет ограничения точности. При работе с большими значениями используется BigInt.

Расширенная версия проверки:

function isDivisibleBig(value, divisor) {
  try {
    const bigValue = BigInt(value);
    const bigDivisor = BigInt(divisor);

    if (bigDivisor === 0n) {
      return false;
    }

    return bigValue % bigDivisor === 0n;
  } catch (e) {
    return false;
  }
}

Особенности реализации:

  • использование BigInt исключает переполнение
  • обработка исключений необходима для некорректных строк
  • операция % работает аналогично числовому типу

Встраивание в схемы валидации

При построении систем валидации входных данных логика делимости часто комбинируется с другими ограничениями.

Пример комплексного правила:

function validateTransaction(value) {
  return (
    validator.isInt(value, { min: 1 }) &&
    isDivisible(value, 100)
  );
}

Такая конструкция используется, например, при проверке:

  • кратности суммы платежей
  • корректности шагов интервалов
  • структурированных идентификаторов

Частные случаи делимости

Некоторые правила делимости можно реализовать без операции деления, что повышает производительность при массовой обработке данных.

Делимость на 2

function isDivisibleBy2(value) {
  return validator.isInt(value) && parseInt(value, 10) % 2 === 0;
}

Делимость на 10

function isDivisibleBy10(value) {
  return validator.isInt(value) && value.endsWith("0");
}

Делимость на 3 (через сумму цифр)

function isDivisibleBy3(value) {
  if (!validator.isInt(value)) return false;

  const sum = value
    .split("")
    .filter(char => char >= "0" && char <= "9")
    .reduce((acc, digit) => acc + Number(digit), 0);

  return sum % 3 === 0;
}

Такой подход уменьшает зависимость от арифметики больших чисел и используется в оптимизированных сценариях.

Обработка некорректных данных

Типичные ошибки при проверке делимости:

  • передача нечисловых строк
  • наличие пробелов и символов форматирования
  • пустые строки
  • дробные числа

Защитный слой:

function safeIsDivisible(value, divisor) {
  if (!validator.isNumeric(value)) {
    return false;
  }

  if (!validator.isInt(value)) {
    return false;
  }

  const num = Number(value);

  if (!Number.isFinite(num)) {
    return false;
  }

  if (divisor === 0) {
    return false;
  }

  return num % divisor === 0;
}

Производительность при массовой валидации

При обработке больших массивов данных важно минимизировать:

  • повторные преобразования типов
  • лишние вызовы validator.isInt
  • создание промежуточных объектов

Оптимизированный вариант:

function isDivisibleFast(value, divisor) {
  const num = Number(value);

  if (!Number.isInteger(num)) {
    return false;
  }

  return num % divisor === 0;
}

Такая реализация применяется в потоковой обработке данных и серверных API с высокой нагрузкой.

Комбинирование с цепочками валидации

В системах валидации часто формируется последовательность проверок, где делимость является финальным условием.

Пример логики:

  1. Проверка типа данных
  2. Проверка диапазона
  3. Проверка делимости
function validateStep(value) {
  if (!validator.isInt(value, { min: 10, max: 1000 })) {
    return false;
  }

  if (!isDivisible(value, 7)) {
    return false;
  }

  return true;
}

Такая структура обеспечивает детерминированную обработку входных данных и упрощает трассировку ошибок валидации.