identiconpp/src/checks.cpp

113 lines
3.3 KiB
C++
Raw Normal View History

2018-12-26 18:52:27 +01:00
/* This file is part of identiconpp.
* Copyright © 2018 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exception>
#include <stdexcept>
#include <algorithm>
#include <cmath>
2018-12-26 18:52:27 +01:00
#include "identiconpp.hpp"
#include "debug.hpp"
void Identiconpp::check_entropy(const string &digest, algorithm type)
2018-12-26 18:52:27 +01:00
{
if (std::any_of(digest.begin(), digest.end(), not_hex))
{
throw std::invalid_argument
(
"Colors must consist of hexadecimal digits (" + digest + ")."
);
}
2018-12-26 18:52:27 +01:00
uint16_t entropy_provided;
uint16_t entropy_required;
switch (type)
{
case algorithm::ltr_symmetric:
2018-12-26 18:52:27 +01:00
{
// Every char is 4 bit
entropy_provided = digest.length() * 4;
// We need bits for each field in half of the columns, +1 column if
// they are uneven. Then we need enough bits to pick a color.
entropy_required = (_columns / 2 + _columns % 2) * _rows
+ std::floor(std::log2(_foreground.size())) + 1;
2018-12-26 18:52:27 +01:00
break;
}
2018-12-27 05:21:40 +01:00
case algorithm::ltr_asymmetric:
{
entropy_provided = digest.length() * 4;
entropy_required = _columns * _rows
+ std::floor(std::log2(_foreground.size())) + 1;
2018-12-27 05:21:40 +01:00
break;
}
case algorithm::sigil:
2018-12-26 18:52:27 +01:00
{
if (_foreground.size() > 256)
{
throw std::invalid_argument(
"sigil algorithm does not support more than 256 colors.");
}
2019-01-01 16:40:34 +01:00
entropy_provided = digest.length() * 4;
2018-12-26 18:52:27 +01:00
entropy_required = (_columns / 2 + _columns % 2) * _rows + 8;
break;
}
}
ttdebug << "entropy_provided=" << std::to_string(entropy_provided)
<< ", entropy_required=" << std::to_string(entropy_required) << '\n';
if (entropy_provided < entropy_required)
{
throw std::invalid_argument(
"Passed digest \"" + digest + "\" is not capable of providing " +
std::to_string(entropy_required) + " bits of entropy.");
}
}
bool Identiconpp::not_hex(const char c)
{
if (c >= 0x61 && c <= 0x66)
{ // a-f
return false;
}
2019-01-02 11:18:43 +01:00
if (c >= 0x41 && c <= 0x46)
{ // A-F
return false;
}
2018-12-26 18:52:27 +01:00
if (c >= 0x30 && c <= 0x39)
{ // 0-9
return false;
}
return true;
}
void Identiconpp::check_color(const string &color)
{
if (color.length() != 8)
{
throw std::invalid_argument
(
"Colors must consist of exactly 8 digits(" + color + ")."
);
}
if (std::any_of(color.begin(), color.end(), not_hex))
{
throw std::invalid_argument
(
"Colors must consist of hexadecimal digits (" + color + ")."
);
}
}