From cae37e147d25088d3a2c745e637603ed6e0823f4 Mon Sep 17 00:00:00 2001 From: Luca Heltai Date: Wed, 1 Apr 2020 11:14:21 +0200 Subject: [PATCH] Encode and decode Base64 format. --- doc/news/changes/minor/20200401LucaHeltai | 4 ++ include/deal.II/base/utilities.h | 33 ++++++++++++++- source/base/utilities.cc | 40 +++++++++++++++++++ tests/base/utilities_encode64_decode64_01.cc | 40 +++++++++++++++++++ .../utilities_encode64_decode64_01.output | 10 +++++ 5 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 doc/news/changes/minor/20200401LucaHeltai create mode 100644 tests/base/utilities_encode64_decode64_01.cc create mode 100644 tests/base/utilities_encode64_decode64_01.output diff --git a/doc/news/changes/minor/20200401LucaHeltai b/doc/news/changes/minor/20200401LucaHeltai new file mode 100644 index 0000000000..0be81cc88e --- /dev/null +++ b/doc/news/changes/minor/20200401LucaHeltai @@ -0,0 +1,4 @@ +New: Utilities::encode_base64() and Utilities::decode_base64() allow to encode and decode binary strings +to and from Base64 ASCII format. +
+(Luca Heltai, 2020/04/01) diff --git a/include/deal.II/base/utilities.h b/include/deal.II/base/utilities.h index 04218bd02b..059b617232 100644 --- a/include/deal.II/base/utilities.h +++ b/include/deal.II/base/utilities.h @@ -156,7 +156,7 @@ namespace Utilities /** * If the library is configured with ZLIB, then this function assumes that the * input string has been compressed using the compress() function, and returns - * the original decompresses string. + * the original decompressed string. * * If the library was not configured with ZLIB enabled, the returned string * is identical to the input string. @@ -171,6 +171,37 @@ namespace Utilities std::string decompress(const std::string &compressed_input); + /** + * Encodes the binary input as a base64 string. + * + * Base64 is a group of binary-to-text encoding schemes that represent binary + * data in an ASCII string format by translating it into a radix-64 + * representation. Base64 is designed to carry data stored in binary formats + * across channels that only reliably support text content. It is used also + * to store binary formats in a machine independent way. + * + * @param binary_input A vector of characters, representing your input as + * binary data. + * @return A string containing the binary input as a base64 string. + * + * @author Luca Heltai, 2020. + */ + std::string + encode_base64(const std::vector &binary_input); + + /** + * Decodes a base64 string into a binary output. + * + * This is the inverse of the encode_base64() function above. + * + * @param base64_input A string that contains the input in base64 format. + * @return A vector of characters that represents your input as binary data. + * + * @author Luca Heltai, 2020. + */ + std::vector + decode_base64(const std::string &base64_input); + /** * Convert a number @p value to a string, with as many digits as given to * fill with leading zeros. diff --git a/source/base/utilities.cc b/source/base/utilities.cc index d809793fa9..ef0db02b21 100644 --- a/source/base/utilities.cc +++ b/source/base/utilities.cc @@ -28,6 +28,9 @@ #include #include +#include +#include +#include DEAL_II_DISABLE_EXTRA_DIAGNOSTICS #include #include @@ -428,6 +431,43 @@ namespace Utilities + std::string + encode_base64(const std::vector &binary_input) + { + using namespace boost::archive::iterators; + using It = base64_from_binary< + transform_width::const_iterator, 6, 8>>; + auto base64 = std::string(It(binary_input.begin()), It(binary_input.end())); + // Add padding. + return base64.append((3 - binary_input.size() % 3) % 3, '='); + } + + + + std::vector + decode_base64(const std::string &base64_input) + { + using namespace boost::archive::iterators; + using It = + transform_width, 8, 6>; + auto binary = std::vector(It(base64_input.begin()), + It(base64_input.end())); + // Remove padding. + auto length = base64_input.size(); + if (binary.size() > 2 && base64_input[length - 1] == '=' && + base64_input[length - 2] == '=') + { + binary.erase(binary.end() - 2, binary.end()); + } + else if (binary.size() > 1 && base64_input[length - 1] == '=') + { + binary.erase(binary.end() - 1, binary.end()); + } + return binary; + } + + + std::string int_to_string(const unsigned int value, const unsigned int digits) { diff --git a/tests/base/utilities_encode64_decode64_01.cc b/tests/base/utilities_encode64_decode64_01.cc new file mode 100644 index 0000000000..4182bdfee8 --- /dev/null +++ b/tests/base/utilities_encode64_decode64_01.cc @@ -0,0 +1,40 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2020 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE.md at +// the top level directory of deal.II. +// +// --------------------------------------------------------------------- + + +// test Utilities::encode_base64/decode_base64 on a few strings + +#include + +#include "../tests.h" + +void +test(const std::string &input) +{ + deallog << "Encoding: " << input << std::endl; + auto encoded = Utilities::encode_base64({input.begin(), input.end()}); + deallog << "Encoded: " << std::string(encoded.begin(), encoded.end()) + << std::endl; + deallog << "Decoded: " << Utilities::decode_base64(encoded) << std::endl; +} + +int +main() +{ + initlog(); + test("Hello"); + test("deal.II rocks!"); + test("1234"); +} diff --git a/tests/base/utilities_encode64_decode64_01.output b/tests/base/utilities_encode64_decode64_01.output new file mode 100644 index 0000000000..5f198acd3c --- /dev/null +++ b/tests/base/utilities_encode64_decode64_01.output @@ -0,0 +1,10 @@ + +DEAL::Encoding: Hello +DEAL::Encoded: SGVsbG8= +DEAL::Decoded: H e l l o +DEAL::Encoding: deal.II rocks! +DEAL::Encoded: ZGVhbC5JSSByb2NrcyE= +DEAL::Decoded: d e a l . I I r o c k s ! +DEAL::Encoding: 1234 +DEAL::Encoded: MTIzNA== +DEAL::Decoded: 1 2 3 4 -- 2.39.5