Files
thehub/testing/streaming/Encoders.cpp
T

171 lines
6.3 KiB
C++
Raw Permalink Normal View History

2020-07-05 12:24:26 +02:00
/*
* This file is part of the Flowee project
2020-07-05 14:03:27 +02:00
* Copyright (C) 2012-2016 The Bitcoin Core developers
2021-06-20 22:44:44 +02:00
* Copyright (C) 2020 Tom Zander <tom@flowee.org>
2020-07-05 12:24:26 +02:00
*
* 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, either version 3 of the License, or
* (at your option) any later version.
*
* 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 "Encoders.h"
2026-05-14 13:13:40 +02:00
#include "crypto/compat/endian.h" // for bswap_16
2020-07-05 12:24:26 +02:00
#include <utilstrencodings.h>
#include <base58.h>
#include <serialize.h> // for begin_ptr etc
2022-12-11 20:05:46 +01:00
#include <QJsonDocument>
2020-07-05 12:24:26 +02:00
2020-07-05 18:59:09 +02:00
static const unsigned char ParseHex_expected[65] = {
0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, 0x48,
0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, 0xb7,
0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, 0x09,
0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, 0xde,
0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, 0x38,
0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, 0x12,
0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, 0x8d,
0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, 0x1d,
0x5f
};
void TestEncoders::testUtilParseHex()
{
std::vector<unsigned char> result;
std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
// Basic test vector
result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
compare(result, expected);
// Spaces between bytes must be supported
result = ParseHex("12 34 56 78");
QVERIFY(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
// Stop parsing at invalid value
result = ParseHex("1234 invalid 1234");
QVERIFY(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34);
}
void TestEncoders::testUtilHexString()
{
QCOMPARE(
HexStr(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)),
"04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
QCOMPARE(HexStr(ParseHex_expected, ParseHex_expected + 5, true), "04 67 8a fd b0");
QCOMPARE(HexStr(ParseHex_expected, ParseHex_expected, true), "");
std::vector<unsigned char> ParseHex_vec(ParseHex_expected, ParseHex_expected + 5);
QCOMPARE(HexStr(ParseHex_vec, true), "04 67 8a fd b0");
}
void TestEncoders::testUtilIsHex()
{
QVERIFY(IsHex("00"));
QVERIFY(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
QVERIFY(IsHex("ff"));
QVERIFY(IsHex("FF"));
QVERIFY(!IsHex(""));
QVERIFY(!IsHex("0"));
QVERIFY(!IsHex("a"));
QVERIFY(!IsHex("eleven"));
QVERIFY(!IsHex("00xx00"));
QVERIFY(!IsHex("0x0000"));
}
2020-07-05 12:24:26 +02:00
void TestEncoders::base32TestVectors()
{
static const std::string vstrIn[] = {"","f","fo","foo","foob","fooba","foobar"};
static const std::string vstrOut[] = {"","my======","mzxq====","mzxw6===","mzxw6yq=","mzxw6ytb","mzxw6ytboi======"};
for (unsigned int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
{
std::string strEnc = EncodeBase32(vstrIn[i]);
QVERIFY(strEnc == vstrOut[i]);
std::string strDec = DecodeBase32(vstrOut[i]);
QVERIFY(strDec == vstrIn[i]);
}
}
void TestEncoders::base58Encode()
{
2022-12-11 20:05:46 +01:00
QFile in(":/base58_encode_decode.json");
QVERIFY(in.open(QIODevice::ReadOnly));
auto testDoc = QJsonDocument::fromJson(in.readAll());
QVERIFY(testDoc.isArray());
auto tests = testDoc.array();
for (auto row = tests.begin(); row != tests.end(); ++row) {
auto test = row->toArray();
assert(test.count() >= 2); // Allow for extra stuff (useful for comments)
auto sourceData = ParseHex(test[0].toString().toLatin1());
std::string base58string = test[1].toString().toStdString();
QVERIFY(Base58::encode(reinterpret_cast<const unsigned char*>(sourceData.data()), sourceData.size()) == base58string);
2020-07-05 12:24:26 +02:00
}
}
void TestEncoders::base58Decode()
{
2022-12-11 20:05:46 +01:00
QFile in(":/base58_encode_decode.json");
QVERIFY(in.open(QIODevice::ReadOnly));
auto testDoc = QJsonDocument::fromJson(in.readAll());
QVERIFY(testDoc.isArray());
auto tests = testDoc.array();
2020-07-05 12:24:26 +02:00
2022-12-11 20:05:46 +01:00
std::vector<unsigned char> result;
for (auto row = tests.begin(); row != tests.end(); ++row) {
auto test = row->toArray();
2020-07-05 12:24:26 +02:00
assert (test.size() >= 2); // Allow for extra stuff (useful for comments)
2022-12-11 20:05:46 +01:00
auto expected = ParseHex(test[0].toString().toLatin1());
std::string base58string = test[1].toString().toStdString();
QVERIFY(Base58::decode(base58string, result));
QCOMPARE(result.size(), expected.size());
QVERIFY(std::equal(result.begin(), result.end(), expected.begin()));
2020-07-05 12:24:26 +02:00
}
2022-12-11 20:05:46 +01:00
QVERIFY(!Base58::decode("invalid", result));
2020-07-05 12:24:26 +02:00
// check that DecodeBase58 skips whitespace, but still fails with unexpected non-whitespace at the end.
2022-12-11 20:05:46 +01:00
QVERIFY(!Base58::decode(" \t\n\v\f\r skip \r\f\v\n\t a", result));
QVERIFY( Base58::decode(" \t\n\v\f\r skip \r\f\v\n\t ", result));
2020-07-05 12:24:26 +02:00
std::vector<unsigned char> expected = ParseHex("971a55");
compare(result, expected);
}
void TestEncoders::base64TestVectors()
{
static const std::string vstrIn[] = {"","f","fo","foo","foob","fooba","foobar"};
static const std::string vstrOut[] = {"","Zg==","Zm8=","Zm9v","Zm9vYg==","Zm9vYmE=","Zm9vYmFy"};
for (unsigned int i=0; i<sizeof(vstrIn)/sizeof(vstrIn[0]); i++)
{
std::string strEnc = EncodeBase64(vstrIn[i]);
QVERIFY(strEnc == vstrOut[i]);
std::string strDec = DecodeBase64(strEnc);
QVERIFY(strDec == vstrIn[i]);
}
}
2020-07-05 14:03:27 +02:00
void TestEncoders::bswap()
{
uint16_t u1 = 0x1234;
uint32_t u2 = 0x56789abc;
uint64_t u3 = 0xdef0123456789abc;
uint16_t e1 = 0x3412;
uint32_t e2 = 0xbc9a7856;
uint64_t e3 = 0xbc9a78563412f0de;
QCOMPARE(bswap_16(u1), e1);
QCOMPARE(bswap_32(u2), e2);
QCOMPARE(bswap_64(u3), e3);
}