File: base32-coding-decoding.cpp

package info (click to toggle)
keysmith 25.08.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,276 kB
  • sloc: cpp: 11,649; xml: 352; sh: 121; makefile: 3
file content (130 lines) | stat: -rw-r--r-- 2,874 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * 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"