Skip to content

Commit

Permalink
Add Base32 extended hex encoder and decoder (GH #534)
Browse files Browse the repository at this point in the history
I'm not sure if this is what the fellow in the issue wanted, but we are missing it. Also see https://stackoverflow.com/q/47325517/608639
  • Loading branch information
noloader committed Nov 28, 2017
1 parent 0db1ef2 commit 8530b58
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 8 deletions.
50 changes: 47 additions & 3 deletions base32.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
// base32.cpp - written and placed in the public domain by Frank Palazzolo, based on hex.cpp by Wei Dai
// extended hex alphabet added by JW in November, 2017.

#include "pch.h"
#include "base32.h"

NAMESPACE_BEGIN(CryptoPP)
ANONYMOUS_NAMESPACE_BEGIN

const byte s_vecUpper[] = "ABCDEFGHIJKMNPQRSTUVWXYZ23456789";
const byte s_vecLower[] = "abcdefghijkmnpqrstuvwxyz23456789";
const byte s_stdUpper[] = "ABCDEFGHIJKMNPQRSTUVWXYZ23456789";
const byte s_stdLower[] = "abcdefghijkmnpqrstuvwxyz23456789";
const byte s_hexUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUV";
const byte s_hexLower[] = "0123456789abcdefghijklmnopqrstuv";

const int s_array[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
Expand All @@ -27,14 +31,33 @@ const int s_array[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};

const int s_hexArray[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};

ANONYMOUS_NAMESPACE_END

void Base32Encoder::IsolatedInitialize(const NameValuePairs &parameters)
{
bool uppercase = parameters.GetValueWithDefault(Name::Uppercase(), true);
m_filter->Initialize(CombinedNameValuePairs(
parameters,
MakeParameters(Name::EncodingLookupArray(), uppercase ? &s_vecUpper[0] : &s_vecLower[0], false)(Name::Log2Base(), 5, true)));
MakeParameters(Name::EncodingLookupArray(), uppercase ? &s_stdUpper[0] : &s_stdLower[0], false)(Name::Log2Base(), 5, true)));
}

void Base32Decoder::IsolatedInitialize(const NameValuePairs &parameters)
Expand All @@ -50,4 +73,25 @@ const int *Base32Decoder::GetDefaultDecodingLookupArray()
return s_array;
}

void Base32HexEncoder::IsolatedInitialize(const NameValuePairs &parameters)
{
bool uppercase = parameters.GetValueWithDefault(Name::Uppercase(), true);
m_filter->Initialize(CombinedNameValuePairs(
parameters,
MakeParameters(Name::EncodingLookupArray(), uppercase ? &s_hexUpper[0] : &s_hexLower[0], false)(Name::Log2Base(), 5, true)));
}

void Base32HexDecoder::IsolatedInitialize(const NameValuePairs &parameters)
{
BaseN_Decoder::IsolatedInitialize(CombinedNameValuePairs(
parameters,
MakeParameters(Name::DecodingLookupArray(), GetDefaultDecodingLookupArray(), false)(Name::Log2Base(), 5, true)));
}

// Unrolled initialization, http://github.com/weidai11/cryptopp/issues/376
const int *Base32HexDecoder::GetDefaultDecodingLookupArray()
{
return s_hexArray;
}

NAMESPACE_END
76 changes: 71 additions & 5 deletions base32.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// base32.h - written and placed in the public domain by Frank Palazzolo, based on hex.cpp by Wei Dai
// extended hex alphabet added by JW in November, 2017.

//! \file
//! \brief Classes for Base32Encoder and Base32Decoder
//! \file base32.h
//! \brief Classes for Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder

#ifndef CRYPTOPP_BASE32_H
#define CRYPTOPP_BASE32_H
Expand All @@ -14,6 +15,7 @@ NAMESPACE_BEGIN(CryptoPP)
//! \class Base32Encoder
//! \brief Base32 encodes data
//! \details Converts data to base32. The default code is based on <A HREF="http://www.ietf.org/proceedings/51/I-D/draft-ietf-idn-dude-02.txt">Differential Unicode Domain Encoding (DUDE) (draft-ietf-idn-dude-02.txt)</A>.
//! \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder
class Base32Encoder : public SimpleProxyFilter
{
public:
Expand All @@ -25,7 +27,7 @@ class Base32Encoder : public SimpleProxyFilter
//! \param terminator the terminator appeand after processing
//! \details Base32Encoder() constructs a default encoder. The constructor lacks fields for padding and
//! line breaks. You must use IsolatedInitialize() to change the default padding character or suppress it.
//! \sa IsolatedInitialize() for an example of modifying a Base32Encoder after construction.
//! \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder
Base32Encoder(BufferedTransformation *attachment = NULLPTR, bool uppercase = true, int groupSize = 0, const std::string &separator = ":", const std::string &terminator = "")
: SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment)
{
Expand All @@ -51,13 +53,14 @@ class Base32Encoder : public SimpleProxyFilter
//! encoder.IsolatedInitialize(params);</pre>
//! \details If you change the encoding alphabet, then you will need to change the decoding alphabet \a and
//! the decoder's lookup table.
//! \sa Base32Decoder::IsolatedInitialize() for an example of changing a Base32Decoder's lookup table.
//! \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder
void IsolatedInitialize(const NameValuePairs &parameters);
};

//! \class Base32Decoder
//! \brief Base32 decodes data
//! \details Decode base32 data. The default code is based on <A HREF="http://www.ietf.org/proceedings/51/I-D/draft-ietf-idn-dude-02.txt">Differential Unicode Domain Encoding (DUDE) (draft-ietf-idn-dude-02.txt)</A>.
//! \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder
class Base32Decoder : public BaseN_Decoder
{
public:
Expand All @@ -82,7 +85,70 @@ class Base32Decoder : public BaseN_Decoder
//! Base32Decoder decoder;
//! AlgorithmParameters params = MakeParameters(Name::DecodingLookupArray(),(const int *)lookup);
//! decoder.IsolatedInitialize(params);</pre>
//! \sa Base32Encoder::IsolatedInitialize() for an example of changing a Base32Encoder's alphabet.
//! \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder
void IsolatedInitialize(const NameValuePairs &parameters);

private:
//! \brief Provides the default decoding lookup table
//! \return default decoding lookup table
static const int * CRYPTOPP_API GetDefaultDecodingLookupArray();
};

//! \class Base32HexEncoder
//! \brief Base32 encodes data using extended hex
//! \details Converts data to base32 using extended hex alphabet. The alphabet is different than Base32Encoder.
//! \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder, <A HREF="http://tools.ietf.org/html/rfc4648#page-10">RFC 4648, Base 32 Encoding with Extended Hex Alphabet</A>.
//! \since Crypto++ 6.0
class Base32HexEncoder : public SimpleProxyFilter
{
public:
//! \brief Construct a Base32HexEncoder
//! \param attachment a BufferedTrasformation to attach to this object
//! \param uppercase a flag indicating uppercase output
//! \param groupSize the size of the grouping
//! \param separator the separator to use between groups
//! \param terminator the terminator appeand after processing
//! \details Base32HexEncoder() constructs a default encoder. The constructor lacks fields for padding and
//! line breaks. You must use IsolatedInitialize() to change the default padding character or suppress it.
//! \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder
Base32HexEncoder(BufferedTransformation *attachment = NULLPTR, bool uppercase = true, int groupSize = 0, const std::string &separator = ":", const std::string &terminator = "")
: SimpleProxyFilter(new BaseN_Encoder(new Grouper), attachment)
{
IsolatedInitialize(MakeParameters(Name::Uppercase(), uppercase)(Name::GroupSize(), groupSize)(Name::Separator(), ConstByteArrayParameter(separator))(Name::Terminator(), ConstByteArrayParameter(terminator)));
}

//! \brief Initialize or reinitialize this object, without signal propagation
//! \param parameters a set of NameValuePairs used to initialize this object
//! \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable
//! number of arbitrarily typed arguments. IsolatedInitialize() does not call Initialize() on attached
//! transformations. If initialization should be propagated, then use the Initialize() function.
//! \details The following code modifies the padding and line break parameters for an encoder:
//! <pre>
//! Base32HexEncoder encoder;
//! AlgorithmParameters params = MakeParameters(Pad(), false)(InsertLineBreaks(), false);
//! encoder.IsolatedInitialize(params);</pre>
void IsolatedInitialize(const NameValuePairs &parameters);
};

//! \class Base32HexDecoder
//! \brief Base32 extended hex decodes data
//! \brief Base32 decodes data using extended hex alphabet. The alphabet is different than Base32Decoder.
//! \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder, <A HREF="http://tools.ietf.org/html/rfc4648#page-10">RFC 4648, Base 32 Encoding with Extended Hex Alphabet</A>.
//! \since Crypto++ 6.0
class Base32HexDecoder : public BaseN_Decoder
{
public:
//! \brief Construct a Base32HexDecoder
//! \param attachment a BufferedTrasformation to attach to this object
//! \sa Base32Encoder, Base32Decoder, Base32HexEncoder and Base32HexDecoder
Base32HexDecoder(BufferedTransformation *attachment = NULLPTR)
: BaseN_Decoder(GetDefaultDecodingLookupArray(), 5, attachment) {}

//! \brief Initialize or reinitialize this object, without signal propagation
//! \param parameters a set of NameValuePairs used to initialize this object
//! \details IsolatedInitialize() is used to initialize or reinitialize an object using a variable
//! number of arbitrarily typed arguments. IsolatedInitialize() does not call Initialize() on attached
//! transformations. If initialization should be propagated, then use the Initialize() function.
void IsolatedInitialize(const NameValuePairs &parameters);

private:
Expand Down

0 comments on commit 8530b58

Please sign in to comment.