File indexing completed on 2024-05-05 05:53:09
0001 /* 0002 * SPDX-License-Identifier: GPL-3.0-or-later 0003 * SPDX-FileCopyrightText: 2020 Johan Ouwerkerk <jm.ouwerkerk@gmail.com> 0004 */ 0005 #include "base32/base32.h" 0006 0007 #include <QTest> 0008 #include <QtDebug> 0009 0010 class Base32CodingDecodingTest: public QObject 0011 { 0012 Q_OBJECT 0013 private Q_SLOTS: 0014 void testSample(void); 0015 void testSample_data(void); 0016 }; 0017 0018 static int lastPadBits(int data) 0019 { 0020 switch (data) { 0021 case 7: 0022 return 3; 0023 case 5: 0024 return 1; 0025 case 4: 0026 return 4; 0027 case 2: 0028 return 2; 0029 default: 0030 return 0; 0031 } 0032 } 0033 0034 static int outputSize(int data) 0035 { 0036 switch (data) { 0037 case 8: 0038 return 5; 0039 case 7: 0040 return 4; 0041 case 5: 0042 return 3; 0043 case 4: 0044 return 2; 0045 case 2: 0046 return 1; 0047 default: 0048 return 0; 0049 } 0050 } 0051 0052 static void define_test_data(void) 0053 { 0054 QTest::addColumn<QString>("input"); 0055 QTest::addColumn<QByteArray>("expected"); 0056 } 0057 0058 static void define_test_case(const QString &input, int len, char value) 0059 { 0060 static const QString testCase(QLatin1String("size: %1: '%2' ... 0x%3")); 0061 QByteArray expected; 0062 int outputSz = outputSize(len); 0063 expected.reserve(outputSz); 0064 expected.resize(outputSz); 0065 expected.fill('\x0'); 0066 if (len > 0) { 0067 expected[expected.size() - 1] = value; 0068 } 0069 0070 QTest::newRow(qPrintable(testCase.arg(len).arg(input).arg(QLatin1String(expected.toHex())))) << input << expected; 0071 } 0072 0073 static inline QChar pick(int v) 0074 { 0075 return v < 26 ? QLatin1Char('A' + v) : QLatin1Char('2' + v - 26); 0076 } 0077 0078 static void define_test_case(int len) 0079 { 0080 QString prefix; 0081 QByteArray output; 0082 int padBits = lastPadBits(len); 0083 for(int i = 3; i < len; ++i) { 0084 prefix += QLatin1Char('A'); 0085 } 0086 0087 for (int b = 0; b < 256; ++b) { 0088 int i1 = ((b << padBits) >> 10) & 0x1F; 0089 int i2 = (b >> (5 - padBits)) & 0x1F; 0090 int i3 = (b << padBits) & 0x1F; 0091 0092 QString input = prefix; 0093 if (len >= 3) { 0094 input += pick(i1); 0095 } 0096 input += pick(i2); 0097 input += pick(i3); 0098 0099 while(input.size() < 8) { 0100 input += QLatin1Char('='); 0101 } 0102 define_test_case(input, len, b); 0103 } 0104 } 0105 0106 void Base32CodingDecodingTest::testSample(void) 0107 { 0108 QFETCH(QString, input); 0109 QFETCH(QByteArray, expected); 0110 0111 QByteArray work(expected.size(), '\x0'); 0112 0113 QCOMPARE(base32::decode(input, work.data(), work.size()), std::optional<size_t>(expected.size())); 0114 QCOMPARE(work, expected); 0115 } 0116 0117 void Base32CodingDecodingTest::testSample_data(void) 0118 { 0119 define_test_data(); 0120 QTest::newRow(qPrintable(QLatin1String("the empty string"))) << QString(QLatin1String("")) << QByteArray(); 0121 define_test_case(2); 0122 define_test_case(4); 0123 define_test_case(5); 0124 define_test_case(7); 0125 define_test_case(8); 0126 } 0127 0128 QTEST_APPLESS_MAIN(Base32CodingDecodingTest) 0129 0130 #include "base32-coding-decoding.moc"