This commit is contained in:
53
.gitignore
vendored
53
.gitignore
vendored
@ -1,51 +1,2 @@
|
||||
# ---> C++
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Bazel
|
||||
bazel-*
|
||||
*.bazel*
|
||||
WORKSPACE.bazel
|
||||
BUILD.bazel
|
||||
|
||||
# Dirs
|
||||
build
|
||||
bin
|
||||
obj
|
||||
lib
|
||||
doc
|
||||
cov
|
||||
usr
|
||||
|
||||
# IDE
|
||||
.vscode
|
||||
build*
|
||||
.cache
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.21)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
project(libbasen
|
||||
VERSION 1.1.1
|
||||
DESCRIPTION "c++20 encoding/decoding from arbitrary base"
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
||||
set(CXX_FLAGS "-Wall -Wextra -Werror -Wno-unused-result -O3")
|
||||
|
||||
if(DEFINED BASEN_SHARED_LIBS)
|
||||
set(BUILD_SHARED_LIBS ${BASEN_SHARED_LIBS})
|
||||
endif()
|
||||
|
||||
set(OBJS
|
||||
base58
|
||||
base64
|
||||
baseN
|
||||
hex
|
||||
Exception
|
||||
hash/sha256
|
||||
)
|
||||
set(SRCS)
|
||||
foreach(OBJ ${OBJS})
|
||||
list(APPEND SRCS "src/${OBJ}.cpp")
|
||||
endforeach()
|
||||
|
||||
add_library(basen ${SRCS})
|
||||
add_library(basen::basen ALIAS basen)
|
||||
target_include_directories(basen PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>
|
||||
)
|
||||
144
Makefile
144
Makefile
@ -1,144 +0,0 @@
|
||||
-l =
|
||||
|
||||
SHARED ?= false
|
||||
DEBUG ?= false
|
||||
USRDIR ?= /usr
|
||||
|
||||
.PHONY: build i install uni uninstall\
|
||||
tools library tests docs cov clean
|
||||
|
||||
LIB = basen
|
||||
|
||||
TOOLS = ${LIB}
|
||||
|
||||
OBJS =\
|
||||
hex\
|
||||
baseN\
|
||||
base58\
|
||||
base64\
|
||||
hash/sha256\
|
||||
Exception
|
||||
|
||||
TESTS =\
|
||||
test-hex\
|
||||
test-baseN\
|
||||
test-base58\
|
||||
test-base64\
|
||||
hash/test-sha256\
|
||||
test-Exception
|
||||
|
||||
ifeq (${origin CC}, default)
|
||||
CC = g++
|
||||
endif
|
||||
|
||||
CFLAGS = -std=c++20 -Wall -Wextra -Werror -Wno-unused-result -fPIC
|
||||
|
||||
ifneq (${DEBUG}, false)
|
||||
CFLAGS += -fsanitize=address,undefined -g -O0
|
||||
-g = -g
|
||||
else
|
||||
CFLAGS += -O3
|
||||
endif
|
||||
|
||||
ifneq (${SHARED}, false)
|
||||
CFLAGS += -Xlinker -rpath=${LIBDIR}
|
||||
-lLIB = -l:lib${LIB}${-g}.so
|
||||
else
|
||||
-lLIB = -l:lib${LIB}${-g}.a
|
||||
endif
|
||||
|
||||
SRCDIR = src
|
||||
INCDIR = include
|
||||
OBJDIR = obj
|
||||
BINDIR = bin
|
||||
LIBDIR = lib
|
||||
TESTDIR = test
|
||||
USRLIB = ${USRDIR}/lib
|
||||
USRBIN = ${USRDIR}/bin
|
||||
USRINC = ${USRDIR}/include
|
||||
DIRS =\
|
||||
${BINDIR}\
|
||||
${BINDIR}/hash\
|
||||
${BINDIR}/tools\
|
||||
${OBJDIR}\
|
||||
${OBJDIR}/hash\
|
||||
${LIBDIR}\
|
||||
|
||||
build: library tools
|
||||
|
||||
i: install
|
||||
install:\
|
||||
build\
|
||||
${USRINC}/${LIB}.hpp\
|
||||
${patsubst %, ${USRINC}/${LIB}/%.hpp, ${OBJS}}\
|
||||
${patsubst %, ${USRLIB}/lib${LIB}${-g}%, .so .a}\
|
||||
${patsubst %, ${USRBIN}/%${-g}, ${TOOLS}}
|
||||
|
||||
uni: uninstall
|
||||
uninstall:
|
||||
rm -f ${USRINC}/${LIB}.hpp
|
||||
rm -f ${patsubst %, ${USRINC}/${LIB}/%.hpp, ${OBJS}}
|
||||
rm -f ${patsubst %, ${USRLIB}/lib${LIB}${-g}%, .so .a}
|
||||
rm -f ${patsubst %, ${USRBIN}/%${-g}, ${TOOLS}}
|
||||
|
||||
docs:
|
||||
doxygen Doxyfile
|
||||
|
||||
cover: ${DIRS} ${patsubst %, ${BINDIR}/%${-g}-cov, ${TESTS}}
|
||||
rm -f **/*.gcda
|
||||
${patsubst %, ./${BINDIR}/%${-g}-cov;, ${TESTS}}
|
||||
mkdir -p cov
|
||||
gcovr --html-nested cov/index.html --txt --exclude-throw-branches
|
||||
|
||||
${OBJDIR}/%${-g}-cov.o: ${SRCDIR}/%.cpp ${INCDIR}/${LIB}/%.hpp
|
||||
${CC} -o $@ -c $< -I${INCDIR} ${-l} ${CFLAGS} --coverage
|
||||
|
||||
${BINDIR}/%${-g}-cov: ${TESTDIR}/%.cpp ${patsubst %, ${OBJDIR}/%${-g}-cov.o, ${OBJS}}
|
||||
${CC} -o $@ $^ -I${INCDIR} ${-l} -lgtest -lgcov ${CFLAGS}
|
||||
|
||||
clean:
|
||||
rm -rf ${DIRS} doc cov
|
||||
|
||||
ifneq (${OBJS},)
|
||||
|
||||
library: ${DIRS} ${patsubst %, ${LIBDIR}/lib${LIB}${-g}%, .so .a}
|
||||
|
||||
${OBJDIR}/%${-g}.o: ${SRCDIR}/%.cpp ${INCDIR}/${LIB}/%.hpp
|
||||
${CC} -o $@ -c $< -I${INCDIR} ${-l} ${CFLAGS}
|
||||
|
||||
${LIBDIR}/lib${LIB}${-g}.so: ${patsubst %, ${OBJDIR}/%${-g}.o, ${OBJS}}
|
||||
${CC} -shared -o $@ $^
|
||||
|
||||
${LIBDIR}/lib${LIB}${-g}.a: ${patsubst %, ${OBJDIR}/%${-g}.o, ${OBJS}}
|
||||
ar rcs $@ $^
|
||||
|
||||
${USRINC}/%: ${INCDIR}/%
|
||||
install -Dm644 $< $@
|
||||
|
||||
${USRLIB}/lib${LIB}${-g}%: ${LIBDIR}/lib${LIB}${-g}%
|
||||
install -Dm755 $< $@
|
||||
|
||||
endif
|
||||
ifneq (${TOOLS},)
|
||||
|
||||
tools: library ${DIRS} ${patsubst %, ${BINDIR}/tools/%${-g}, ${TOOLS}}
|
||||
|
||||
${BINDIR}/tools/%${-g}: ${SRCDIR}/tools/%.cpp ${patsubst %, ${OBJDIR}/%${-g}.o, ${OBJS}}
|
||||
${CC} -o $@ $< -I${INCDIR} -L${LIBDIR} ${-l} ${-lLIB} ${CFLAGS}
|
||||
|
||||
${USRBIN}/%${-g}: ${BINDIR}/tools/%${-g}
|
||||
install -Dm755 $< $@
|
||||
|
||||
endif
|
||||
ifneq (${TESTS},)
|
||||
|
||||
tests: library ${DIRS} ${patsubst %, ${BINDIR}/%${-g}, ${TESTS}}
|
||||
echo ${patsubst %, && ./${BINDIR}/%${-g}, ${TESTS}}
|
||||
|
||||
${BINDIR}/%${-g}: ${TESTDIR}/%.cpp ${patsubst %, ${OBJDIR}/%${-g}.o, ${OBJS}}
|
||||
${CC} -o $@ $< -I${INCDIR} -L${LIBDIR} ${-l} ${-lLIB} -lgtest ${CFLAGS}
|
||||
|
||||
endif
|
||||
|
||||
${DIRS}:
|
||||
mkdir -p $@
|
||||
44
README.md
44
README.md
@ -13,8 +13,7 @@ c++20 encoding/decoding from arbitrary base
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Package](#package)
|
||||
- [Make](#make)
|
||||
- [CMake](#cmake)
|
||||
- [Meson](#meson)
|
||||
- [Documentation](#documentation)
|
||||
- [Usage](#usage)
|
||||
- [Contributing](#contributing)
|
||||
@ -25,35 +24,14 @@ c++20 encoding/decoding from arbitrary base
|
||||
|
||||
[](https://repology.org/project/libbasen/versions)
|
||||
|
||||
### Make
|
||||
### Meson
|
||||
|
||||
For cli tool you should have [argparse](https://github.com/p-ranav/argparse) as make dependency.
|
||||
|
||||
Install:
|
||||
```
|
||||
make -j $(nproc)
|
||||
sudo make i USRDIR=(Your installation dir)
|
||||
```
|
||||
Uninstall:
|
||||
```
|
||||
sudo make uni USRDIR=(Your installation dir)
|
||||
```
|
||||
|
||||
### CMake
|
||||
|
||||
For using as dependency only (without cli tool, test, coverage, docs)
|
||||
|
||||
```
|
||||
set(BASEN_SHARED_LIBS ON)
|
||||
include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
basen
|
||||
GIT_REPOSITORY https://github.com/vSEK1RO/libbasen.git
|
||||
GIT_TAG latest
|
||||
)
|
||||
FetchContent_MakeAvailable(basen)
|
||||
|
||||
target_link_libraries(MyProject PRIVATE basen::basen)
|
||||
meson setup build --buildtype=release
|
||||
cd build
|
||||
meson install
|
||||
```
|
||||
|
||||
## Documentation
|
||||
@ -65,11 +43,7 @@ Available [here](https://vsek1ro.github.io/libbasen)
|
||||
libbasen package provides `basen` cli tool. Below are examples of use:
|
||||
```
|
||||
echo "hello world" | basen -t hex > encoded.data
|
||||
```
|
||||
```
|
||||
basen -t hex -d < encoded.data > decoded.data
|
||||
```
|
||||
```
|
||||
echo "arbitrary alphabet" | basen -a "0123ABCD"
|
||||
```
|
||||
|
||||
@ -84,15 +58,17 @@ Now we would like to implement the following features:
|
||||
|
||||
For build with with debug flags:
|
||||
```
|
||||
make -j $(nproc) DEBUG=
|
||||
meson setup build-dev -Db_coverage=true
|
||||
cd build-dev
|
||||
meson compile
|
||||
```
|
||||
For build tests (needed gtest package as dependency):
|
||||
```
|
||||
make tests -j $(nproc) DEBUG=
|
||||
meson test
|
||||
```
|
||||
For generating coverage:
|
||||
```
|
||||
make cover -j $(nproc) DEBUG=
|
||||
ninja coverage
|
||||
```
|
||||
|
||||
[⬆️ Contents](#contents)
|
||||
|
||||
1
config.hpp.in
Normal file
1
config.hpp.in
Normal file
@ -0,0 +1 @@
|
||||
#define BASEN_VER_STR "@ver_str@"
|
||||
@ -1,6 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <source_location>
|
||||
#include <string>
|
||||
|
||||
1
include/meson.build
Normal file
1
include/meson.build
Normal file
@ -0,0 +1 @@
|
||||
install_subdir('.', install_dir: 'include', exclude_files: ['meson.build'])
|
||||
34
meson.build
Normal file
34
meson.build
Normal file
@ -0,0 +1,34 @@
|
||||
project(
|
||||
'basen',
|
||||
'cpp',
|
||||
version: '1.1.1',
|
||||
default_options: {
|
||||
'cpp_std': 'c++20',
|
||||
'cpp_args': '-Wall -Wextra -Werror -Wno-unused-result',
|
||||
},
|
||||
license: 'LGPL-3.0-only',
|
||||
license_files: 'LICENSE',
|
||||
meson_version: '>=1.10.0',
|
||||
)
|
||||
|
||||
configure_file(
|
||||
input: 'config.hpp.in',
|
||||
output: 'config.hpp',
|
||||
configuration: {'ver_str': meson.project_version()},
|
||||
)
|
||||
|
||||
include = include_directories('.', 'include')
|
||||
|
||||
subdir('include')
|
||||
subdir('src')
|
||||
|
||||
basen_dep = declare_dependency(
|
||||
link_with: libbasen,
|
||||
include_directories: include,
|
||||
)
|
||||
|
||||
if get_option('buildtype') == 'debug'
|
||||
subdir('test')
|
||||
endif
|
||||
|
||||
subdir('tools')
|
||||
@ -1,12 +1,11 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <basen/baseN.hpp>
|
||||
#include <basen/Exception.hpp>
|
||||
|
||||
static constexpr auto log256 = std::log(256);
|
||||
static constexpr auto log256 = 5.545177444479562;
|
||||
|
||||
namespace baseN
|
||||
{
|
||||
@ -40,7 +39,7 @@ namespace baseN
|
||||
std::span<const uint8_t> dv(std::find_if(data.begin(), data.end(), [](uint8_t item)
|
||||
{ return item != 0; }),
|
||||
data.end());
|
||||
if (dv.size() > std::numeric_limits<size_t>::max() / log256)
|
||||
if (dv.size() > (double)std::numeric_limits<size_t>::max() / log256)
|
||||
{
|
||||
throw basen::Exception(basen::Exception::Code::OVERFLOW);
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <basen/baseN.hpp>
|
||||
#include <basen/Exception.hpp>
|
||||
|
||||
11
src/meson.build
Normal file
11
src/meson.build
Normal file
@ -0,0 +1,11 @@
|
||||
libbasen = library(
|
||||
'basen',
|
||||
'hex.cpp',
|
||||
'baseN.cpp',
|
||||
'base58.cpp',
|
||||
'base64.cpp',
|
||||
'Exception.cpp',
|
||||
'hash/sha256.cpp',
|
||||
include_directories: [include],
|
||||
install: true,
|
||||
)
|
||||
@ -27,9 +27,3 @@ TEST(Exception, code)
|
||||
EXPECT_EQ(uint32_t(e.code()), uint32_t(basen::Exception::Code::BASE));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@ -21,9 +21,3 @@ TEST(base58, decodeCheck)
|
||||
EXPECT_EQ(test.first, hex::encode(decodeCheck(test.second)));
|
||||
EXPECT_THROW(decodeCheck("incorrect"), basen::Exception);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
61
test/base64.cpp
Normal file
61
test/base64.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include <utility>
|
||||
|
||||
#include <basen/base64.hpp>
|
||||
#include <basen/Exception.hpp>
|
||||
#include <basen/hex.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace base64 {
|
||||
|
||||
TEST(base64, isValid)
|
||||
{
|
||||
std::vector<std::pair<bool, std::string>> tests = {
|
||||
{true, "12=="},
|
||||
{true, "123="},
|
||||
{true, "1234"},
|
||||
{false, "1==="},
|
||||
{false, "?!*"},
|
||||
};
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, isValid(it.second));
|
||||
}
|
||||
std::vector<std::pair<std::string, std::string>> tests = {
|
||||
{"", ""},
|
||||
{"BKUEpQ==", "04a504a5"},
|
||||
{"aGVsbG8=", "68656c6c6f"},
|
||||
{"aGVsbG9v", "68656c6c6f6f"},
|
||||
};
|
||||
TEST(base64, encode)
|
||||
{
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, encode(hex::decode(it.second)));
|
||||
|
||||
std::vector<uint8_t> data = {0x74, 0x65, 0x73, 0x74};
|
||||
std::string str = "";
|
||||
EXPECT_THROW(encode(data.data(), std::numeric_limits<size_t>::max(), str.data(), str.size()), basen::Exception);
|
||||
EXPECT_THROW(encode(data.data(), data.size(), str.data(), str.size()), basen::Exception);
|
||||
EXPECT_NO_THROW(encode(data.data(), 0, str.data(), str.size()));
|
||||
}
|
||||
TEST(base64, encode_1e7)
|
||||
{
|
||||
std::vector<uint8_t> data(1e7);
|
||||
encode(data);
|
||||
}
|
||||
TEST(base64, decode)
|
||||
{
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(hex::encode(decode(it.first)), it.second);
|
||||
|
||||
std::vector<uint8_t> data = {0x61, 0x6e, 0x6f};
|
||||
EXPECT_THROW(decode("FFF", 3, data.data(), data.size()), basen::Exception);
|
||||
EXPECT_THROW(decode("!@#!", 4, data.data(), data.size()), basen::Exception);
|
||||
EXPECT_THROW(decode("FF==", 2, data.data(), 0), basen::Exception);
|
||||
EXPECT_NO_THROW(decode("", 0, data.data(), 0));
|
||||
}
|
||||
TEST(base64, decode_1e7)
|
||||
{
|
||||
std::string str(1e7, '0');
|
||||
decode(str);
|
||||
}
|
||||
|
||||
}
|
||||
85
test/baseN.cpp
Normal file
85
test/baseN.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include <utility>
|
||||
|
||||
#include <basen/base58.hpp>
|
||||
#include <basen/baseN.hpp>
|
||||
#include <basen/Exception.hpp>
|
||||
#include <basen/hex.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace baseN {
|
||||
|
||||
TEST(baseN, digitsMap)
|
||||
{
|
||||
uint8_t map[256];
|
||||
digitsMap(base58::digits, 58, map);
|
||||
EXPECT_TRUE(std::equal(map, map + 256, base58::map));
|
||||
|
||||
EXPECT_THROW(digitsMap("11", 2, map), basen::Exception);
|
||||
}
|
||||
TEST(baseN, isValid)
|
||||
{
|
||||
std::vector<std::pair<bool, std::string>> tests = {
|
||||
{true, "123"},
|
||||
{false, "@#$"},
|
||||
};
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, isValid(it.second, base58::map));
|
||||
}
|
||||
TEST(baseN, sizeEncoded)
|
||||
{
|
||||
std::vector<std::pair<size_t, std::string>> tests = {
|
||||
{6, "12341234"},
|
||||
{5, "00000000"},
|
||||
};
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, sizeEncoded(hex::decode(it.second), 58));
|
||||
|
||||
EXPECT_THROW(sizeEncoded(hex::decode(""), 0), basen::Exception);
|
||||
}
|
||||
TEST(baseN, sizeDecoded)
|
||||
{
|
||||
std::vector<std::pair<size_t, std::string>> tests = {
|
||||
{3, "qwer"},
|
||||
{5, "1111"},
|
||||
};
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, sizeDecoded(it.second, 58, base58::digits));
|
||||
|
||||
EXPECT_THROW(sizeDecoded("", 0, base58::digits), basen::Exception);
|
||||
}
|
||||
std::vector<std::pair<std::string, std::string>> tests = {
|
||||
{"", ""},
|
||||
{"Ky", "044c"},
|
||||
{"KyK", "f94a"},
|
||||
{"KyKX", "387ae2"},
|
||||
{"KyKXa", "0ccbd755"},
|
||||
{"KyKXaa", "02e62ec963"},
|
||||
{"111KyKX", "000000387ae2"},
|
||||
{"4uqWDRyJZUpS6KKwLAiitndmv7TPFt2bfxVVfhJhgTn3Rh6aQtGHQY6PhhNDpCwSNU8a",
|
||||
"057902f9cebebb68879911002aae743280140a78c4a077405b057902f9cebebb68879911002aae743280140a78c4a077405b"},
|
||||
};
|
||||
TEST(baseN, encode)
|
||||
{
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, encode(hex::decode(it.second), 58, base58::digits));
|
||||
}
|
||||
TEST(baseN, encode_1e3)
|
||||
{
|
||||
std::vector<uint8_t> data(1e3);
|
||||
std::fill(data.begin(), data.end(), 1);
|
||||
encode(data, 58, base58::digits);
|
||||
}
|
||||
TEST(baseN, decode)
|
||||
{
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(hex::encode(decode(it.first, 58, base58::digits, base58::map)), it.second);
|
||||
|
||||
EXPECT_THROW(decode("!@#", 58, base58::digits, base58::map), basen::Exception);
|
||||
}
|
||||
TEST(baseN, decode_1e3)
|
||||
{
|
||||
std::string str(1e3, '2');
|
||||
decode(str, 58, base58::digits, base58::map);
|
||||
}
|
||||
|
||||
}
|
||||
@ -16,9 +16,3 @@ TEST(hash, sha256_1e4)
|
||||
sha256(data);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@ -45,9 +45,3 @@ TEST(hex, decode_1e7)
|
||||
std::string str(1e7, '0');
|
||||
decode(str);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
14
test/meson.build
Normal file
14
test/meson.build
Normal file
@ -0,0 +1,14 @@
|
||||
gtest_dep = dependency('gtest', main: true)
|
||||
|
||||
test_exe = executable(
|
||||
'test_exe',
|
||||
'hex.cpp',
|
||||
'baseN.cpp',
|
||||
'base58.cpp',
|
||||
'base64.cpp',
|
||||
'Exception.cpp',
|
||||
'hash/sha256.cpp',
|
||||
dependencies: [basen_dep, gtest_dep],
|
||||
)
|
||||
|
||||
test('lib', test_exe)
|
||||
@ -1,65 +0,0 @@
|
||||
#include <utility>
|
||||
|
||||
#include <basen/base64.hpp>
|
||||
#include <basen/Exception.hpp>
|
||||
#include <basen/hex.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace base64;
|
||||
|
||||
TEST(base64, isValid)
|
||||
{
|
||||
std::vector<std::pair<bool, std::string>> tests = {
|
||||
{true, "12=="},
|
||||
{true, "123="},
|
||||
{true, "1234"},
|
||||
{false, "1==="},
|
||||
{false, "?!*"},
|
||||
};
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, isValid(it.second));
|
||||
}
|
||||
std::vector<std::pair<std::string, std::string>> tests = {
|
||||
{"", ""},
|
||||
{"BKUEpQ==", "04a504a5"},
|
||||
{"aGVsbG8=", "68656c6c6f"},
|
||||
{"aGVsbG9v", "68656c6c6f6f"},
|
||||
};
|
||||
TEST(base64, encode)
|
||||
{
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, encode(hex::decode(it.second)));
|
||||
|
||||
std::vector<uint8_t> data = {0x74, 0x65, 0x73, 0x74};
|
||||
std::string str = "";
|
||||
EXPECT_THROW(encode(data.data(), std::numeric_limits<size_t>::max(), str.data(), str.size()), basen::Exception);
|
||||
EXPECT_THROW(encode(data.data(), data.size(), str.data(), str.size()), basen::Exception);
|
||||
EXPECT_NO_THROW(encode(data.data(), 0, str.data(), str.size()));
|
||||
}
|
||||
TEST(base64, encode_1e7)
|
||||
{
|
||||
std::vector<uint8_t> data(1e7);
|
||||
encode(data);
|
||||
}
|
||||
TEST(base64, decode)
|
||||
{
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(hex::encode(decode(it.first)), it.second);
|
||||
|
||||
std::vector<uint8_t> data = {0x61, 0x6e, 0x6f};
|
||||
EXPECT_THROW(decode("FFF", 3, data.data(), data.size()), basen::Exception);
|
||||
EXPECT_THROW(decode("!@#!", 4, data.data(), data.size()), basen::Exception);
|
||||
EXPECT_THROW(decode("FF==", 2, data.data(), 0), basen::Exception);
|
||||
EXPECT_NO_THROW(decode("", 0, data.data(), 0));
|
||||
}
|
||||
TEST(base64, decode_1e7)
|
||||
{
|
||||
std::string str(1e7, '0');
|
||||
decode(str);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@ -1,89 +0,0 @@
|
||||
#include <utility>
|
||||
|
||||
#include <basen/base58.hpp>
|
||||
#include <basen/baseN.hpp>
|
||||
#include <basen/Exception.hpp>
|
||||
#include <basen/hex.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
using namespace baseN;
|
||||
|
||||
TEST(baseN, digitsMap)
|
||||
{
|
||||
uint8_t map[256];
|
||||
digitsMap(base58::digits, 58, map);
|
||||
EXPECT_TRUE(std::equal(map, map + 256, base58::map));
|
||||
|
||||
EXPECT_THROW(digitsMap("11", 2, map), basen::Exception);
|
||||
}
|
||||
TEST(baseN, isValid)
|
||||
{
|
||||
std::vector<std::pair<bool, std::string>> tests = {
|
||||
{true, "123"},
|
||||
{false, "@#$"},
|
||||
};
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, isValid(it.second, base58::map));
|
||||
}
|
||||
TEST(baseN, sizeEncoded)
|
||||
{
|
||||
std::vector<std::pair<size_t, std::string>> tests = {
|
||||
{6, "12341234"},
|
||||
{5, "00000000"},
|
||||
};
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, sizeEncoded(hex::decode(it.second), 58));
|
||||
|
||||
EXPECT_THROW(sizeEncoded(hex::decode(""), 0), basen::Exception);
|
||||
}
|
||||
TEST(baseN, sizeDecoded)
|
||||
{
|
||||
std::vector<std::pair<size_t, std::string>> tests = {
|
||||
{3, "qwer"},
|
||||
{5, "1111"},
|
||||
};
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, sizeDecoded(it.second, 58, base58::digits));
|
||||
|
||||
EXPECT_THROW(sizeDecoded("", 0, base58::digits), basen::Exception);
|
||||
}
|
||||
std::vector<std::pair<std::string, std::string>> tests = {
|
||||
{"", ""},
|
||||
{"Ky", "044c"},
|
||||
{"KyK", "f94a"},
|
||||
{"KyKX", "387ae2"},
|
||||
{"KyKXa", "0ccbd755"},
|
||||
{"KyKXaa", "02e62ec963"},
|
||||
{"111KyKX", "000000387ae2"},
|
||||
{"4uqWDRyJZUpS6KKwLAiitndmv7TPFt2bfxVVfhJhgTn3Rh6aQtGHQY6PhhNDpCwSNU8a",
|
||||
"057902f9cebebb68879911002aae743280140a78c4a077405b057902f9cebebb68879911002aae743280140a78c4a077405b"},
|
||||
};
|
||||
TEST(baseN, encode)
|
||||
{
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(it.first, encode(hex::decode(it.second), 58, base58::digits));
|
||||
}
|
||||
TEST(baseN, encode_1e3)
|
||||
{
|
||||
std::vector<uint8_t> data(1e3);
|
||||
std::fill(data.begin(), data.end(), 1);
|
||||
encode(data, 58, base58::digits);
|
||||
}
|
||||
TEST(baseN, decode)
|
||||
{
|
||||
for (auto it : tests)
|
||||
EXPECT_EQ(hex::encode(decode(it.first, 58, base58::digits, base58::map)), it.second);
|
||||
|
||||
EXPECT_THROW(decode("!@#", 58, base58::digits, base58::map), basen::Exception);
|
||||
}
|
||||
TEST(baseN, decode_1e3)
|
||||
{
|
||||
std::string str(1e3, '2');
|
||||
decode(str, 58, base58::digits, base58::map);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
@ -1,10 +1,10 @@
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <argparse/argparse.hpp>
|
||||
|
||||
#include <basen.hpp>
|
||||
#include <config.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
@ -80,6 +80,8 @@ int main(int argc, char *argv[])
|
||||
program.add_argument("-d", "--decode")
|
||||
.help("decode flag")
|
||||
.flag();
|
||||
program.add_argument("-v", "--version")
|
||||
.flag();
|
||||
try
|
||||
{
|
||||
program.parse_args(argc, argv);
|
||||
@ -88,6 +90,10 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
return basen::error(err.what(), program);
|
||||
}
|
||||
if (program.is_used("-v")) {
|
||||
std::cout << BASEN_VER_STR << std::endl;
|
||||
return 0;
|
||||
}
|
||||
if (!program.is_used("-t") && !program.is_used("-a"))
|
||||
{
|
||||
return basen::error("either -t or -a should be provided", program);
|
||||
8
tools/meson.build
Normal file
8
tools/meson.build
Normal file
@ -0,0 +1,8 @@
|
||||
argparse_dep = dependency('argparse')
|
||||
|
||||
executable(
|
||||
'basen',
|
||||
'basen.cpp',
|
||||
dependencies: [basen_dep, argparse_dep],
|
||||
install: true,
|
||||
)
|
||||
Reference in New Issue
Block a user