Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce base64 encode & decode in xeus #404

Merged
merged 2 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ endif ()
# ============

set(XEUS_HEADERS
${XEUS_INCLUDE_DIR}/xeus/xbase64.hpp
${XEUS_INCLUDE_DIR}/xeus/xbasic_fixed_string.hpp
${XEUS_INCLUDE_DIR}/xeus/xcomm.hpp
${XEUS_INCLUDE_DIR}/xeus/xcontrol_messenger.hpp
Expand Down
75 changes: 75 additions & 0 deletions include/xeus/xbase64.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/***************************************************************************
* Copyright (c) Sylvain Corlay and Johan Mabille and Wolf Vollprecht *
* Copyright (c) QuantStack *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#ifndef XEUS_BASE64_HPP
#define XEUS_BASE64_HPP

#include <array>
#include <cstddef>
#include <string>

namespace xeus
{
inline std::string base64decode(const std::string& input)
{
std::array<int, 256> T;
T.fill(-1);
for (std::size_t i = 0; i < 64; ++i)
{
T[std::size_t("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[i])] = int(i);
}

std::string output;
int val = 0;
int valb = -8;
for (char c : input)
{
if (T[std::size_t(c)] == -1)
{
break;
}
val = (val << 6) + T[std::size_t(c)];
valb += 6;
if (valb >= 0)
{
output.push_back(char((val >> valb) & 0xFF));
valb -= 8;
}
}
return output;
}

inline std::string base64encode(const std::string& input)
{
std::string output;
int val = 0;
int valb = -6;
for (char sc : input)
{
unsigned char c = static_cast<unsigned char>(sc);
val = (val << 8) + c;
valb += 8;
while (valb >= 0)
{
output.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(val >> valb) & 0x3F]);
valb -= 6;
}
}
if (valb > -6)
{
output.push_back("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[((val << 8) >> (valb + 8)) & 0x3F]);
}
while (output.size() % 4)
{
output.push_back('=');
}
return output;
}
}
#endif
1 change: 1 addition & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ find_package(doctest REQUIRED)
find_package(Threads)

set(XEUS_TESTS
test_xbase64.cpp
test_xbasic_fixed_string.cpp
test_xhash.cpp
test_xin_memory_history_manager.cpp
Expand Down
36 changes: 36 additions & 0 deletions test/test_xbase64.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/***************************************************************************
* Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht *
* Copyright (c) QuantStack *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#include "doctest/doctest.h"

#include "xeus/xbase64.hpp"

namespace xeus
{
TEST_SUITE("xbase64")
{
TEST_CASE("base64encode")
{
std::string input = "hello world";
std::string expected_output = "aGVsbG8gd29ybGQ=";
std::string encoded = base64encode(input);

REQUIRE(encoded == expected_output);
}

TEST_CASE("base64decode")
{
std::string input = "aGVsbG8gd29ybGQ=";
std::string expected_output = "hello world";
std::string decoded = base64decode(input);

REQUIRE(decoded == expected_output);
}
}
}