Files

103 lines
2.5 KiB
C++

#include "common/Validation.h"
#include <array>
#include <cctype>
#include <regex>
namespace visione::validation
{
namespace
{
char normalizeFiscalCodeChar(char ch)
{
return static_cast<char>(
std::toupper(static_cast<unsigned char>(ch)));
}
int fiscalCodeControlValueForOdd(char ch)
{
static constexpr std::array<int, 26> letterValues{
1, 0, 5, 7, 9, 13, 15, 17, 19, 21, 2, 4, 18,
20, 11, 3, 6, 8, 12, 14, 16, 10, 22, 25, 24, 23};
static constexpr std::array<int, 10> digitValues{1, 0, 5, 7, 9,
13, 15, 17, 19, 21};
if (std::isdigit(static_cast<unsigned char>(ch)))
{
return digitValues[static_cast<size_t>(ch - '0')];
}
return letterValues[static_cast<size_t>(ch - 'A')];
}
int fiscalCodeControlValueForEven(char ch)
{
if (std::isdigit(static_cast<unsigned char>(ch)))
{
return ch - '0';
}
return ch - 'A';
}
} // namespace
bool hasString(const Json::Value &body, const std::string &key)
{
return body.isMember(key) && body[key].isString() &&
!body[key].asString().empty();
}
bool hasNumber(const Json::Value &body, const std::string &key)
{
return body.isMember(key) && body[key].isNumeric();
}
std::vector<std::string> missingStrings(
const Json::Value &body,
std::initializer_list<const char *> keys)
{
std::vector<std::string> missing;
for (const auto *key : keys)
{
if (!hasString(body, key))
{
missing.emplace_back(key);
}
}
return missing;
}
bool isValidEmail(const std::string &email)
{
static const std::regex pattern(R"(^[^@\s]+@[^@\s]+\.[^@\s]+$)");
return std::regex_match(email, pattern);
}
bool isValidFiscalCode(const std::string &fiscalCode)
{
static const std::regex pattern(
R"(^[A-Za-z]{6}[0-9]{2}[ABCDEHLMPRST]{1}[0-9]{2}[A-Za-z][0-9]{3}[A-Za-z]$)");
if (!std::regex_match(fiscalCode, pattern))
{
return false;
}
std::string normalized;
normalized.reserve(fiscalCode.size());
for (char ch : fiscalCode)
{
normalized.push_back(normalizeFiscalCodeChar(ch));
}
int sum = 0;
for (size_t i = 0; i < normalized.size() - 1; ++i)
{
sum += ((i + 1) % 2 == 0) ? fiscalCodeControlValueForEven(normalized[i])
: fiscalCodeControlValueForOdd(normalized[i]);
}
const char expectedControl =
static_cast<char>('A' + (sum % 26));
return normalized.back() == expectedControl;
}
} // namespace visione::validation