1 // basecode.h - originally written and placed in the public domain by Wei Dai
2 
3 /// \file
4 /// \brief Base classes for working with encoders and decoders.
5 
6 #ifndef CRYPTOPP_BASECODE_H
7 #define CRYPTOPP_BASECODE_H
8 
9 #include "cryptlib.h"
10 #include "filters.h"
11 #include "algparam.h"
12 #include "argnames.h"
13 
NAMESPACE_BEGIN(CryptoPP)14 NAMESPACE_BEGIN(CryptoPP)
15 
16 /// \brief Encoder for bases that are a power of 2
17 class CRYPTOPP_DLL BaseN_Encoder : public Unflushable<Filter>
18 {
19 public:
20 	/// \brief Construct a BaseN_Encoder
21 	/// \param attachment a BufferedTransformation to attach to this object
22 	BaseN_Encoder(BufferedTransformation *attachment=NULLPTR)
23 		: m_alphabet(NULLPTR), m_padding(0), m_bitsPerChar(0)
24 		, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
25 			{Detach(attachment);}
26 
27 	/// \brief Construct a BaseN_Encoder
28 	/// \param alphabet table of ASCII characters to use as the alphabet
29 	/// \param log2base the log<sub>2</sub>base
30 	/// \param attachment a BufferedTransformation to attach to this object
31 	/// \param padding the character to use as padding
32 	/// \pre log2base must be between 1 and 7 inclusive
33 	/// \throw InvalidArgument if log2base is not between 1 and 7
34 	BaseN_Encoder(const byte *alphabet, int log2base, BufferedTransformation *attachment=NULLPTR, int padding=-1)
35 		: m_alphabet(NULLPTR), m_padding(0), m_bitsPerChar(0)
36 		, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
37 	{
38 		Detach(attachment);
39 		BaseN_Encoder::IsolatedInitialize(
40 			MakeParameters
41 				(Name::EncodingLookupArray(), alphabet)
42 				(Name::Log2Base(), log2base)
43 				(Name::Pad(), padding != -1)
44 				(Name::PaddingByte(), byte(padding)));
45 	}
46 
47 	void IsolatedInitialize(const NameValuePairs &parameters);
48 	size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
49 
50 private:
51 	const byte *m_alphabet;
52 	int m_padding, m_bitsPerChar, m_outputBlockSize;
53 	int m_bytePos, m_bitPos;
54 	SecByteBlock m_outBuf;
55 };
56 
57 /// \brief Decoder for bases that are a power of 2
58 class CRYPTOPP_DLL BaseN_Decoder : public Unflushable<Filter>
59 {
60 public:
61 	/// \brief Construct a BaseN_Decoder
62 	/// \param attachment a BufferedTransformation to attach to this object
63 	/// \details padding is set to -1, which means use default padding. If not
64 	///   required, then the value must be set via IsolatedInitialize().
65 	BaseN_Decoder(BufferedTransformation *attachment=NULLPTR)
m_lookup(NULLPTR)66 		: m_lookup(NULLPTR), m_bitsPerChar(0)
67 		, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
68 			{Detach(attachment);}
69 
70 	/// \brief Construct a BaseN_Decoder
71 	/// \param lookup table of values
72 	/// \param log2base the log<sub>2</sub>base
73 	/// \param attachment a BufferedTransformation to attach to this object
74 	/// \details log2base is the exponent (like 5 in 2<sup>5</sup>), and not
75 	///   the number of elements (like 32).
76 	/// \details padding is set to -1, which means use default padding. If not
77 	///   required, then the value must be set via IsolatedInitialize().
78 	BaseN_Decoder(const int *lookup, int log2base, BufferedTransformation *attachment=NULLPTR)
m_lookup(NULLPTR)79 		: m_lookup(NULLPTR), m_bitsPerChar(0)
80 		, m_outputBlockSize(0), m_bytePos(0), m_bitPos(0)
81 	{
82 		Detach(attachment);
83 		BaseN_Decoder::IsolatedInitialize(
84 			MakeParameters
85 				(Name::DecodingLookupArray(), lookup)
86 				(Name::Log2Base(), log2base));
87 	}
88 
89 	void IsolatedInitialize(const NameValuePairs &parameters);
90 	size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
91 
92 	/// \brief Initializes BaseN lookup array
93 	/// \param lookup table of values
94 	/// \param alphabet table of ASCII characters
95 	/// \param base the base for the encoder
96 	/// \param caseInsensitive flag indicating whether the alphabet is case sensitivie
97 	/// \pre COUNTOF(lookup) == 256
98 	/// \pre COUNTOF(alphabet) == base
99 	/// \details Internally, the function sets the first 256 elements in the lookup table to
100 	///  their value from the alphabet array or -1. base is the number of element (like 32),
101 	///  and not an exponent (like 5 in 2<sup>5</sup>)
102 	static void CRYPTOPP_API InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive);
103 
104 private:
105 	const int *m_lookup;
106 	int m_bitsPerChar, m_outputBlockSize;
107 	int m_bytePos, m_bitPos;
108 	SecByteBlock m_outBuf;
109 };
110 
111 /// \brief Filter that breaks input stream into groups of fixed size
112 class CRYPTOPP_DLL Grouper : public Bufferless<Filter>
113 {
114 public:
115 	/// \brief Construct a Grouper
116 	/// \param attachment a BufferedTransformation to attach to this object
117 	Grouper(BufferedTransformation *attachment=NULLPTR)
118 		: m_groupSize(0), m_counter(0) {Detach(attachment);}
119 
120 	/// \brief Construct a Grouper
121 	/// \param groupSize the size of the grouping
122 	/// \param separator the separator to use between groups
123 	/// \param terminator the terminator appeand after processing
124 	/// \param attachment a BufferedTransformation to attach to this object
125 	Grouper(int groupSize, const std::string &separator, const std::string &terminator, BufferedTransformation *attachment=NULLPTR)
126 		: m_groupSize(0), m_counter(0)
127 	{
128 		Detach(attachment);
129 		Grouper::IsolatedInitialize(
130 			MakeParameters
131 				(Name::GroupSize(), groupSize)
132 				(Name::Separator(), ConstByteArrayParameter(separator))
133 				(Name::Terminator(), ConstByteArrayParameter(terminator)));
134 	}
135 
136 	void IsolatedInitialize(const NameValuePairs &parameters);
137 	size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking);
138 
139 private:
140 	SecByteBlock m_separator, m_terminator;
141 	size_t m_groupSize, m_counter;
142 };
143 
144 NAMESPACE_END
145 
146 #endif
147