131 lines
2.8 KiB
C++
131 lines
2.8 KiB
C++
/*
|
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
* SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com>
|
|
*/
|
|
#include "base32/base32.h"
|
|
|
|
#include <QTest>
|
|
#include <QtDebug>
|
|
|
|
class Base32CodingDecodingTest: public QObject
|
|
{
|
|
Q_OBJECT
|
|
private Q_SLOTS:
|
|
void testSample(void);
|
|
void testSample_data(void);
|
|
};
|
|
|
|
static int lastPadBits(int data)
|
|
{
|
|
switch (data) {
|
|
case 7:
|
|
return 3;
|
|
case 5:
|
|
return 1;
|
|
case 4:
|
|
return 4;
|
|
case 2:
|
|
return 2;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static int outputSize(int data)
|
|
{
|
|
switch (data) {
|
|
case 8:
|
|
return 5;
|
|
case 7:
|
|
return 4;
|
|
case 5:
|
|
return 3;
|
|
case 4:
|
|
return 2;
|
|
case 2:
|
|
return 1;
|
|
default:
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
static void define_test_data(void)
|
|
{
|
|
QTest::addColumn<QString>("input");
|
|
QTest::addColumn<QByteArray>("expected");
|
|
}
|
|
|
|
static void define_test_case(const QString &input, int len, char value)
|
|
{
|
|
static const QString testCase(QLatin1String("size: %1: '%2' ... 0x%3"));
|
|
QByteArray expected;
|
|
int outputSz = outputSize(len);
|
|
expected.reserve(outputSz);
|
|
expected.resize(outputSz);
|
|
expected.fill('\x0');
|
|
if (len > 0) {
|
|
expected[expected.size() - 1] = value;
|
|
}
|
|
|
|
QTest::newRow(qPrintable(testCase.arg(len).arg(input).arg(QLatin1String(expected.toHex())))) << input << expected;
|
|
}
|
|
|
|
static inline QChar pick(int v)
|
|
{
|
|
return v < 26 ? QLatin1Char('A' + v) : QLatin1Char('2' + v - 26);
|
|
}
|
|
|
|
static void define_test_case(int len)
|
|
{
|
|
QString prefix;
|
|
QByteArray output;
|
|
int padBits = lastPadBits(len);
|
|
for(int i = 3; i < len; ++i) {
|
|
prefix += QLatin1Char('A');
|
|
}
|
|
|
|
for (int b = 0; b < 256; ++b) {
|
|
int i1 = ((b << padBits) >> 10) & 0x1F;
|
|
int i2 = (b >> (5 - padBits)) & 0x1F;
|
|
int i3 = (b << padBits) & 0x1F;
|
|
|
|
QString input = prefix;
|
|
if (len >= 3) {
|
|
input += pick(i1);
|
|
}
|
|
input += pick(i2);
|
|
input += pick(i3);
|
|
|
|
while(input.size() < 8) {
|
|
input += QLatin1Char('=');
|
|
}
|
|
define_test_case(input, len, b);
|
|
}
|
|
}
|
|
|
|
void Base32CodingDecodingTest::testSample(void)
|
|
{
|
|
QFETCH(QString, input);
|
|
QFETCH(QByteArray, expected);
|
|
|
|
QByteArray work(expected.size(), '\x0');
|
|
|
|
QCOMPARE(base32::decode(input, work.data(), work.size()), std::optional<size_t>(expected.size()));
|
|
QCOMPARE(work, expected);
|
|
}
|
|
|
|
void Base32CodingDecodingTest::testSample_data(void)
|
|
{
|
|
define_test_data();
|
|
QTest::newRow(qPrintable(QLatin1String("the empty string"))) << QString(QLatin1String("")) << QByteArray();
|
|
define_test_case(2);
|
|
define_test_case(4);
|
|
define_test_case(5);
|
|
define_test_case(7);
|
|
define_test_case(8);
|
|
}
|
|
|
|
QTEST_APPLESS_MAIN(Base32CodingDecodingTest)
|
|
|
|
#include "base32-coding-decoding.moc"
|