mirror of
https://github.com/arun11299/cpp-jwt.git
synced 2025-05-15 01:08:31 +00:00
Im provements in base64.hpp
This commit is contained in:
parent
da6d4932c3
commit
2290c8733a
5 changed files with 134 additions and 25 deletions
|
@ -7,8 +7,27 @@
|
|||
|
||||
namespace jwt {
|
||||
|
||||
/*!
|
||||
// Returns the maximum number of bytes required to
|
||||
// encode an input byte string of length `n` to base64.
|
||||
inline constexpr
|
||||
size_t encoding_size(size_t n)
|
||||
{
|
||||
return 4 * ((n + 2) / 3);
|
||||
}
|
||||
|
||||
|
||||
// Returns the maximum number of bytes required
|
||||
// to store a decoded base64 byte string.
|
||||
inline constexpr
|
||||
size_t decoding_size(size_t n)
|
||||
{
|
||||
return n / 4 * 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encoding map.
|
||||
* A constexpr helper class for performing base64
|
||||
* encoding on the input byte string.
|
||||
*/
|
||||
class EMap
|
||||
{
|
||||
|
@ -31,21 +50,32 @@ private:
|
|||
};
|
||||
};
|
||||
|
||||
/*!
|
||||
/**
|
||||
* Encodes a sequence of octet into base64 string.
|
||||
* Returns std::string resized to contain only the
|
||||
* encoded data (as usual without null terminator).
|
||||
*
|
||||
* The encoded string is atleast `encoding_size(input len)`
|
||||
* in size.
|
||||
*
|
||||
* Arguments:
|
||||
* @in : Input byte string to be encoded.
|
||||
* @len : Length of the input byte string.
|
||||
*/
|
||||
std::string base64_encode(const char* in, size_t len)
|
||||
{
|
||||
std::string result;
|
||||
result.resize(128);
|
||||
const auto encoded_siz = encoding_size(len);
|
||||
result.resize(encoded_siz);
|
||||
|
||||
constexpr static const EMap emap{};
|
||||
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
for (; i < len - 2; i += 3) {
|
||||
auto& first = in[i];
|
||||
auto& second = in[i+1];
|
||||
auto& third = in[i+2];
|
||||
const auto first = in[i];
|
||||
const auto second = in[i+1];
|
||||
const auto third = in[i+2];
|
||||
|
||||
result[j++] = emap.at( (first >> 2) & 0x3F );
|
||||
result[j++] = emap.at(((first & 0x03) << 4) | ((second & 0xF0) >> 4));
|
||||
|
@ -56,8 +86,8 @@ std::string base64_encode(const char* in, size_t len)
|
|||
switch (len % 3) {
|
||||
case 2:
|
||||
{
|
||||
auto& first = in[i];
|
||||
auto& second = in[i+1];
|
||||
const auto first = in[i];
|
||||
const auto second = in[i+1];
|
||||
|
||||
result[j++] = emap.at( (first >> 2) & 0x3F );
|
||||
result[j++] = emap.at(((first & 0x03) << 4) | ((second & 0xF0) >> 4));
|
||||
|
@ -67,7 +97,7 @@ std::string base64_encode(const char* in, size_t len)
|
|||
}
|
||||
case 1:
|
||||
{
|
||||
auto& first = in[i];
|
||||
const auto first = in[i];
|
||||
|
||||
result[j++] = emap.at((first >> 2) & 0x3F);
|
||||
result[j++] = emap.at((first & 0x03) << 4);
|
||||
|
@ -79,6 +109,8 @@ std::string base64_encode(const char* in, size_t len)
|
|||
break;
|
||||
};
|
||||
|
||||
result.resize(j);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -86,8 +118,10 @@ std::string base64_encode(const char* in, size_t len)
|
|||
|
||||
//======================= Decoder ==========================
|
||||
|
||||
/*
|
||||
/**
|
||||
* Decoding map.
|
||||
* A helper constexpr class for providing interface
|
||||
* to the decoding map for base64.
|
||||
*/
|
||||
class DMap
|
||||
{
|
||||
|
@ -122,12 +156,21 @@ private:
|
|||
};
|
||||
};
|
||||
|
||||
/*!
|
||||
/**
|
||||
* Decodes octet of base64 encoded byte string.
|
||||
*
|
||||
* Returns a std::string with the decoded byte string.
|
||||
*
|
||||
* Arguments:
|
||||
* @in : Encoded base64 byte string.
|
||||
* @len : Length of the encoded input byte string.
|
||||
*/
|
||||
std::string base64_decode(const char* in, size_t len)
|
||||
{
|
||||
std::string result;
|
||||
result.resize(128);
|
||||
const auto decoded_siz = decoding_size(len);
|
||||
result.resize(decoded_siz);
|
||||
|
||||
int i = 0;
|
||||
size_t bytes_rem = len;
|
||||
size_t bytes_wr = 0;
|
||||
|
@ -141,13 +184,13 @@ std::string base64_decode(const char* in, size_t len)
|
|||
// Error case in input
|
||||
if (dmap.at(*in) == -1) return result;
|
||||
|
||||
auto first = dmap.at(in[0]);
|
||||
auto second = dmap.at(in[1]);
|
||||
auto third = dmap.at(in[2]);
|
||||
auto fourth = dmap.at(in[3]);
|
||||
const auto first = dmap.at(in[0]);
|
||||
const auto second = dmap.at(in[1]);
|
||||
const auto third = dmap.at(in[2]);
|
||||
const auto fourth = dmap.at(in[3]);
|
||||
|
||||
result[i] = (first << 2) | (second >> 4);
|
||||
result[i + 1] = (second << 4) | (third >> 2);
|
||||
result[i + 1] = (second << 4) | (third >> 2);
|
||||
result[i + 2] = (third << 6) | fourth;
|
||||
|
||||
bytes_rem -= 4;
|
||||
|
@ -159,24 +202,24 @@ std::string base64_decode(const char* in, size_t len)
|
|||
switch(bytes_rem) {
|
||||
case 4:
|
||||
{
|
||||
auto third = dmap.at(in[2]);
|
||||
auto fourth = dmap.at(in[3]);
|
||||
const auto third = dmap.at(in[2]);
|
||||
const auto fourth = dmap.at(in[3]);
|
||||
result[i + 2] = (third << 6) | fourth;
|
||||
bytes_wr++;
|
||||
//FALLTHROUGH
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
auto second = dmap.at(in[1]);
|
||||
auto third = dmap.at(in[2]);
|
||||
const auto second = dmap.at(in[1]);
|
||||
const auto third = dmap.at(in[2]);
|
||||
result[i + 1] = (second << 4) | (third >> 2);
|
||||
bytes_wr++;
|
||||
//FALLTHROUGH
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
auto first = dmap.at(in[0]);
|
||||
auto second = dmap.at(in[1]);
|
||||
const auto first = dmap.at(in[0]);
|
||||
const auto second = dmap.at(in[1]);
|
||||
result[i] = (first << 2) | (second >> 4);
|
||||
bytes_wr++;
|
||||
}
|
||||
|
@ -187,7 +230,17 @@ std::string base64_decode(const char* in, size_t len)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
/**
|
||||
* Makes the base64 encoded byte string URL safe.
|
||||
* Overwrites/skips few URL unsafe characters
|
||||
* from the input sequence.
|
||||
*
|
||||
* Arguments:
|
||||
* @data : Base64 encoded byte string.
|
||||
* @len : Length of the base64 byte string.
|
||||
*
|
||||
* Returns:
|
||||
* Length of the URL safe base64 encoded byte string.
|
||||
*/
|
||||
size_t base64_uri_encode(char* data, size_t len) noexcept
|
||||
{
|
||||
|
@ -212,7 +265,15 @@ size_t base64_uri_encode(char* data, size_t len) noexcept
|
|||
return j;
|
||||
}
|
||||
|
||||
/*!
|
||||
/**
|
||||
* Decodes an input URL safe base64 encoded byte string.
|
||||
*
|
||||
* NOTE: To be used only for decoding URL safe base64 encoded
|
||||
* byte string.
|
||||
*
|
||||
* Arguments:
|
||||
* @data : URL safe base64 encoded byte string.
|
||||
* @len : Length of the input byte string.
|
||||
*/
|
||||
std::string base64_uri_decode(const char* data, size_t len)
|
||||
{
|
||||
|
|
0
include/jwt/error_codes.hpp
Normal file
0
include/jwt/error_codes.hpp
Normal file
0
include/jwt/exceptions.hpp
Normal file
0
include/jwt/exceptions.hpp
Normal file
BIN
include/jwt/test/test_base64
Executable file
BIN
include/jwt/test/test_base64
Executable file
Binary file not shown.
48
include/jwt/test/test_base64.cc
Normal file
48
include/jwt/test/test_base64.cc
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include "jwt/base64.hpp"
|
||||
|
||||
void base64_test_encode()
|
||||
{
|
||||
std::string input = "ArunMu";
|
||||
std::string output = jwt::base64_encode(input.c_str(), input.length());
|
||||
assert (output == "QXJ1bk11");
|
||||
|
||||
input = "Something really strange!!";
|
||||
output = jwt::base64_encode(input.c_str(), input.length());
|
||||
assert (output == "U29tZXRoaW5nIHJlYWxseSBzdHJhbmdlISE=");
|
||||
|
||||
input = "Do you want to know something more stranger ????";
|
||||
output = jwt::base64_encode(input.c_str(), input.length());
|
||||
assert (output == "RG8geW91IHdhbnQgdG8ga25vdyBzb21ldGhpbmcgbW9yZSBzdHJhbmdlciA/Pz8/");
|
||||
|
||||
input = R"({"a" : "b", "c" : [1,2,3,4,5]})";
|
||||
output = jwt::base64_encode(input.c_str(), input.length());
|
||||
assert (output == "eyJhIiA6ICJiIiwgImMiIDogWzEsMiwzLDQsNV19");
|
||||
}
|
||||
|
||||
void base64_test_decode()
|
||||
{
|
||||
std::string input = "QXJ1bk11";
|
||||
std::string output = jwt::base64_decode(input.c_str(), input.length());
|
||||
assert (output == "ArunMu");
|
||||
|
||||
input = "U29tZXRoaW5nIHJlYWxseSBzdHJhbmdlISE=";
|
||||
output = jwt::base64_decode(input.c_str(), input.length());
|
||||
assert (output == "Something really strange!!");
|
||||
|
||||
input = "RG8geW91IHdhbnQgdG8ga25vdyBzb21ldGhpbmcgbW9yZSBzdHJhbmdlciA/Pz8/";
|
||||
output = jwt::base64_decode(input.c_str(), input.length());
|
||||
assert (output == "Do you want to know something more stranger ????");
|
||||
|
||||
input = "eyJhIiA6ICJiIiwgImMiIDogWzEsMiwzLDQsNV19";
|
||||
output = jwt::base64_decode(input.c_str(), input.length());
|
||||
assert (output == R"({"a" : "b", "c" : [1,2,3,4,5]})");
|
||||
}
|
||||
|
||||
int main() {
|
||||
base64_test_encode();
|
||||
base64_test_decode();
|
||||
return 0;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue