]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Encode and decode Base64 format.
authorLuca Heltai <luca.heltai@sissa.it>
Wed, 1 Apr 2020 09:14:21 +0000 (11:14 +0200)
committerLuca Heltai <luca.heltai@sissa.it>
Fri, 3 Apr 2020 14:54:02 +0000 (16:54 +0200)
doc/news/changes/minor/20200401LucaHeltai [new file with mode: 0644]
include/deal.II/base/utilities.h
source/base/utilities.cc
tests/base/utilities_encode64_decode64_01.cc [new file with mode: 0644]
tests/base/utilities_encode64_decode64_01.output [new file with mode: 0644]

diff --git a/doc/news/changes/minor/20200401LucaHeltai b/doc/news/changes/minor/20200401LucaHeltai
new file mode 100644 (file)
index 0000000..0be81cc
--- /dev/null
@@ -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.
+<br>
+(Luca Heltai, 2020/04/01)
index 04218bd02b6e1bebef19d08bd600f5b013d9c1fa..059b6172328b8c3cb181b0e642b0be63e1679930 100644 (file)
@@ -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<unsigned char> &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<unsigned char>
+  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.
index d809793fa9778f3d586c58c57c7c6227ac5a724b..ef0db02b21649e9fcfdf5c0ff75e5efded1fb5ef 100644 (file)
@@ -28,6 +28,9 @@
 #include <deal.II/base/thread_local_storage.h>
 #include <deal.II/base/utilities.h>
 
+#include <boost/archive/iterators/base64_from_binary.hpp>
+#include <boost/archive/iterators/binary_from_base64.hpp>
+#include <boost/archive/iterators/transform_width.hpp>
 DEAL_II_DISABLE_EXTRA_DIAGNOSTICS
 #include <boost/iostreams/copy.hpp>
 #include <boost/lexical_cast.hpp>
@@ -428,6 +431,43 @@ namespace Utilities
 
 
 
+  std::string
+  encode_base64(const std::vector<unsigned char> &binary_input)
+  {
+    using namespace boost::archive::iterators;
+    using It = base64_from_binary<
+      transform_width<std::vector<unsigned char>::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<unsigned char>
+  decode_base64(const std::string &base64_input)
+  {
+    using namespace boost::archive::iterators;
+    using It =
+      transform_width<binary_from_base64<std::string::const_iterator>, 8, 6>;
+    auto binary = std::vector<unsigned char>(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 (file)
index 0000000..4182bdf
--- /dev/null
@@ -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 <deal.II/base/utilities.h>
+
+#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 (file)
index 0000000..5f198ac
--- /dev/null
@@ -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

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.