Crypto++ 8.7
Free C++ class library of cryptographic schemes
basecode.cpp
1// basecode.cpp - originally written and placed in the public domain by Wei Dai
2
3#include "pch.h"
4#include "config.h"
5
6#if CRYPTOPP_MSC_VERSION
7# pragma warning(disable: 4100)
8#endif
9
10#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
11# pragma GCC diagnostic ignored "-Wunused-value"
12#endif
13
14#ifndef CRYPTOPP_IMPORTS
15
16#include "basecode.h"
17#include "fltrimpl.h"
18#include <ctype.h>
19
20NAMESPACE_BEGIN(CryptoPP)
21
23{
24 parameters.GetRequiredParameter("BaseN_Encoder", Name::EncodingLookupArray(), m_alphabet);
25
26 parameters.GetRequiredIntParameter("BaseN_Encoder", Name::Log2Base(), m_bitsPerChar);
27 if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
28 throw InvalidArgument("BaseN_Encoder: Log2Base must be between 1 and 7 inclusive");
29
30 byte padding;
31 bool pad;
32 if (parameters.GetValue(Name::PaddingByte(), padding))
33 pad = parameters.GetValueWithDefault(Name::Pad(), true);
34 else
35 pad = false;
36 m_padding = pad ? padding : -1;
37
38 m_bytePos = m_bitPos = 0;
39
40 int i = 8;
41 while (i%m_bitsPerChar != 0)
42 i += 8;
43 m_outputBlockSize = i/m_bitsPerChar;
44
45 m_outBuf.New(m_outputBlockSize);
46}
47
48size_t BaseN_Encoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
49{
50 FILTER_BEGIN;
51 while (m_inputPosition < length)
52 {
53 if (m_bytePos == 0)
54 memset(m_outBuf, 0, m_outputBlockSize);
55
56 {
57 unsigned int b = begin[m_inputPosition++], bitsLeftInSource = 8;
58 while (true)
59 {
60 CRYPTOPP_ASSERT(m_bitsPerChar-m_bitPos >= 0);
61 unsigned int bitsLeftInTarget = (unsigned int)(m_bitsPerChar-m_bitPos);
62 m_outBuf[m_bytePos] |= b >> (8-bitsLeftInTarget);
63 if (bitsLeftInSource >= bitsLeftInTarget)
64 {
65 m_bitPos = 0;
66 ++m_bytePos;
67 bitsLeftInSource -= bitsLeftInTarget;
68 if (bitsLeftInSource == 0)
69 break;
70 b <<= bitsLeftInTarget;
71 b &= 0xff;
72 }
73 else
74 {
75 m_bitPos += bitsLeftInSource;
76 break;
77 }
78 }
79 }
80
81 CRYPTOPP_ASSERT(m_bytePos <= m_outputBlockSize);
82 if (m_bytePos == m_outputBlockSize)
83 {
84 int i;
85 for (i=0; i<m_bytePos; i++)
86 {
87 CRYPTOPP_ASSERT(m_outBuf[i] < (1 << m_bitsPerChar));
88 m_outBuf[i] = m_alphabet[m_outBuf[i]];
89 }
90 FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
91
92 m_bytePos = m_bitPos = 0;
93 }
94 }
95 if (messageEnd)
96 {
97 if (m_bitPos > 0)
98 ++m_bytePos;
99
100 int i;
101 for (i=0; i<m_bytePos; i++)
102 m_outBuf[i] = m_alphabet[m_outBuf[i]];
103
104 if (m_padding != -1 && m_bytePos > 0)
105 {
106 memset(m_outBuf+m_bytePos, m_padding, m_outputBlockSize-m_bytePos);
107 m_bytePos = m_outputBlockSize;
108 }
109 FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
110 m_bytePos = m_bitPos = 0;
111 }
112 FILTER_END_NO_MESSAGE_END;
113}
114
116{
117 parameters.GetRequiredParameter("BaseN_Decoder", Name::DecodingLookupArray(), m_lookup);
118
119 parameters.GetRequiredIntParameter("BaseN_Decoder", Name::Log2Base(), m_bitsPerChar);
120 if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
121 throw InvalidArgument("BaseN_Decoder: Log2Base must be between 1 and 7 inclusive");
122
123 m_bytePos = m_bitPos = 0;
124
125 int i = m_bitsPerChar;
126 while (i%8 != 0)
127 i += m_bitsPerChar;
128 m_outputBlockSize = i/8;
129
130 m_outBuf.New(m_outputBlockSize);
131}
132
133size_t BaseN_Decoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
134{
135 FILTER_BEGIN;
136 while (m_inputPosition < length)
137 {
138 unsigned int value;
139 value = m_lookup[begin[m_inputPosition++]];
140 if (value >= 256)
141 continue;
142
143 if (m_bytePos == 0 && m_bitPos == 0)
144 memset(m_outBuf, 0, m_outputBlockSize);
145
146 {
147 int newBitPos = m_bitPos + m_bitsPerChar;
148 if (newBitPos <= 8)
149 m_outBuf[m_bytePos] |= value << (8-newBitPos);
150 else
151 {
152 m_outBuf[m_bytePos] |= value >> (newBitPos-8);
153 m_outBuf[m_bytePos+1] |= value << (16-newBitPos);
154 }
155
156 m_bitPos = newBitPos;
157 while (m_bitPos >= 8)
158 {
159 m_bitPos -= 8;
160 ++m_bytePos;
161 }
162 }
163
164 if (m_bytePos == m_outputBlockSize)
165 {
166 FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
167 m_bytePos = m_bitPos = 0;
168 }
169 }
170 if (messageEnd)
171 {
172 FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
173 m_bytePos = m_bitPos = 0;
174 }
175 FILTER_END_NO_MESSAGE_END;
176}
177
178void BaseN_Decoder::InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive)
179{
180 std::fill(lookup, lookup+256, -1);
181
182 for (unsigned int i=0; i<base; i++)
183 {
184 // Debug asserts for 'lookup[alphabet[i]] == -1' removed because the self tests
185 // have unusual tests that try to break the encoders and decoders. Tests include
186 // a string of the same characters. I.,e., a string of stars like '********...'.
187 if (caseInsensitive && isalpha(alphabet[i]))
188 {
189 lookup[toupper(alphabet[i])] = i;
190 lookup[tolower(alphabet[i])] = i;
191 }
192 else
193 {
194 lookup[alphabet[i]] = i;
195 }
196 }
197}
198
199void Grouper::IsolatedInitialize(const NameValuePairs &parameters)
200{
201 m_groupSize = parameters.GetIntValueWithDefault(Name::GroupSize(), 0);
202 ConstByteArrayParameter separator, terminator;
203 if (m_groupSize)
204 parameters.GetRequiredParameter("Grouper", Name::Separator(), separator);
205 else
206 parameters.GetValue(Name::Separator(), separator);
207 parameters.GetValue(Name::Terminator(), terminator);
208
209 m_separator.Assign(separator.begin(), separator.size());
210 m_terminator.Assign(terminator.begin(), terminator.size());
211 m_counter = 0;
212}
213
214size_t Grouper::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
215{
216 FILTER_BEGIN;
217 if (m_groupSize)
218 {
219 while (m_inputPosition < length)
220 {
221 if (m_counter == m_groupSize)
222 {
223 FILTER_OUTPUT(1, m_separator, m_separator.size(), 0);
224 m_counter = 0;
225 }
226
227 size_t len;
228 FILTER_OUTPUT2(2, len = STDMIN(length-m_inputPosition, m_groupSize-m_counter),
229 begin+m_inputPosition, len, 0);
230 m_inputPosition += len;
231 m_counter += len;
232 }
233 }
234 else
235 FILTER_OUTPUT(3, begin, length, 0);
236
237 if (messageEnd)
238 {
239 FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd);
240 m_counter = 0;
241 }
242 FILTER_END_NO_MESSAGE_END
243}
244
245NAMESPACE_END
246
247#endif
Base classes for working with encoders and decoders.
static void InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive)
Initializes BaseN lookup array.
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:25
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:84
size_t size() const
Length of the memory block.
Definition: algparam.h:88
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
An invalid argument was detected.
Definition: cryptlib.h:203
Interface for retrieving values given their names.
Definition: cryptlib.h:322
T GetValueWithDefault(const char *name, T defaultValue) const
Get a named value.
Definition: cryptlib.h:392
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:379
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition: cryptlib.h:424
CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const
Retrieves a required name/value pair.
Definition: cryptlib.h:483
void GetRequiredParameter(const char *className, const char *name, T &value) const
Retrieves a required name/value pair.
Definition: cryptlib.h:468
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:1126
void Assign(const T *ptr, size_type len)
Set contents and size from an array.
Definition: secblock.h:898
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:867
Library configuration file.
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:655
Crypto++ library namespace.
const char * DecodingLookupArray()
const byte *
Definition: argnames.h:76
const char * GroupSize()
int
Definition: argnames.h:71
const char * PaddingByte()
byte
Definition: argnames.h:73
const char * EncodingLookupArray()
const byte *
Definition: argnames.h:75
const char * Pad()
bool
Definition: argnames.h:72
const char * Terminator()
ConstByteArrayParameter.
Definition: argnames.h:69
const char * Log2Base()
int
Definition: argnames.h:74
const char * Separator()
ConstByteArrayParameter.
Definition: argnames.h:68
Precompiled header file.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68