Crypto++  5.6.5
Free C++ class library of cryptographic schemes
basecode.cpp
1 // basecode.cpp - 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 
20 NAMESPACE_BEGIN(CryptoPP)
21 
22 void BaseN_Encoder::IsolatedInitialize(const NameValuePairs &parameters)
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 
48 size_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 
133 size_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 
178 void 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  if (caseInsensitive && isalpha(alphabet[i]))
185  {
186  CRYPTOPP_ASSERT(lookup[toupper(alphabet[i])] == -1);
187  lookup[toupper(alphabet[i])] = i;
188  CRYPTOPP_ASSERT(lookup[tolower(alphabet[i])] == -1);
189  lookup[tolower(alphabet[i])] = i;
190  }
191  else
192  {
193  CRYPTOPP_ASSERT(lookup[alphabet[i]] == -1);
194  lookup[alphabet[i]] = i;
195  }
196  }
197 }
198 
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 
214 size_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 
245 NAMESPACE_END
246 
247 #endif
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:29
An invalid argument was detected.
Definition: cryptlib.h:184
void GetRequiredParameter(const char *className, const char *name, T &value) const
Retrieves a required name/value pair.
Definition: cryptlib.h:408
size_type size() const
Provides the count of elements in the SecBlock.
Definition: secblock.h:524
size_t size() const
Length of the memory block.
Definition: algparam.h:93
Library configuration file.
void New(size_type newSize)
Change size without preserving contents.
Definition: secblock.h:647
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:89
static void InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive)
Intializes BaseN lookup array.
Definition: basecode.cpp:178
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
Definition: basecode.cpp:199
bool GetValue(const char *name, T &value) const
Get a named value.
Definition: cryptlib.h:337
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
Definition: basecode.cpp:115
int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition: cryptlib.h:382
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Definition: basecode.cpp:48
void Assign(const T *ptr, size_type len)
Set contents and size from an array.
Definition: secblock.h:544
void GetRequiredIntParameter(const char *className, const char *name, int &value) const
Retrieves a required name/value pair.
Definition: cryptlib.h:423
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:477
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:62
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Definition: basecode.cpp:214
Crypto++ library namespace.
Encoder for bases that are a power of 2.
Definition: basecode.h:18
Base classes for working with encoders and decoders.
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Definition: basecode.cpp:133
Interface for retrieving values given their names.
Definition: cryptlib.h:279