Crypto++
basecode.cpp
1 // basecode.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 
5 #ifndef CRYPTOPP_IMPORTS
6 
7 #include "basecode.h"
8 #include "fltrimpl.h"
9 #include <ctype.h>
10 
11 NAMESPACE_BEGIN(CryptoPP)
12 
13 void BaseN_Encoder::IsolatedInitialize(const NameValuePairs &parameters)
14 {
15  parameters.GetRequiredParameter("BaseN_Encoder", Name::EncodingLookupArray(), m_alphabet);
16 
17  parameters.GetRequiredIntParameter("BaseN_Encoder", Name::Log2Base(), m_bitsPerChar);
18  if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
19  throw InvalidArgument("BaseN_Encoder: Log2Base must be between 1 and 7 inclusive");
20 
21  byte padding;
22  bool pad;
23  if (parameters.GetValue(Name::PaddingByte(), padding))
24  pad = parameters.GetValueWithDefault(Name::Pad(), true);
25  else
26  pad = false;
27  m_padding = pad ? padding : -1;
28 
29  m_bytePos = m_bitPos = 0;
30 
31  int i = 8;
32  while (i%m_bitsPerChar != 0)
33  i += 8;
34  m_outputBlockSize = i/m_bitsPerChar;
35 
36  m_outBuf.New(m_outputBlockSize);
37 }
38 
39 size_t BaseN_Encoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
40 {
41  FILTER_BEGIN;
42  while (m_inputPosition < length)
43  {
44  if (m_bytePos == 0)
45  memset(m_outBuf, 0, m_outputBlockSize);
46 
47  {
48  unsigned int b = begin[m_inputPosition++], bitsLeftInSource = 8;
49  while (true)
50  {
51  assert(m_bitPos < m_bitsPerChar);
52  unsigned int bitsLeftInTarget = m_bitsPerChar-m_bitPos;
53  m_outBuf[m_bytePos] |= b >> (8-bitsLeftInTarget);
54  if (bitsLeftInSource >= bitsLeftInTarget)
55  {
56  m_bitPos = 0;
57  ++m_bytePos;
58  bitsLeftInSource -= bitsLeftInTarget;
59  if (bitsLeftInSource == 0)
60  break;
61  b <<= bitsLeftInTarget;
62  b &= 0xff;
63  }
64  else
65  {
66  m_bitPos += bitsLeftInSource;
67  break;
68  }
69  }
70  }
71 
72  assert(m_bytePos <= m_outputBlockSize);
73  if (m_bytePos == m_outputBlockSize)
74  {
75  int i;
76  for (i=0; i<m_bytePos; i++)
77  {
78  assert(m_outBuf[i] < (1 << m_bitsPerChar));
79  m_outBuf[i] = m_alphabet[m_outBuf[i]];
80  }
81  FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
82 
83  m_bytePos = m_bitPos = 0;
84  }
85  }
86  if (messageEnd)
87  {
88  if (m_bitPos > 0)
89  ++m_bytePos;
90 
91  int i;
92  for (i=0; i<m_bytePos; i++)
93  m_outBuf[i] = m_alphabet[m_outBuf[i]];
94 
95  if (m_padding != -1 && m_bytePos > 0)
96  {
97  memset(m_outBuf+m_bytePos, m_padding, m_outputBlockSize-m_bytePos);
98  m_bytePos = m_outputBlockSize;
99  }
100  FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
101  m_bytePos = m_bitPos = 0;
102  }
103  FILTER_END_NO_MESSAGE_END;
104 }
105 
106 void BaseN_Decoder::IsolatedInitialize(const NameValuePairs &parameters)
107 {
108  parameters.GetRequiredParameter("BaseN_Decoder", Name::DecodingLookupArray(), m_lookup);
109 
110  parameters.GetRequiredIntParameter("BaseN_Decoder", Name::Log2Base(), m_bitsPerChar);
111  if (m_bitsPerChar <= 0 || m_bitsPerChar >= 8)
112  throw InvalidArgument("BaseN_Decoder: Log2Base must be between 1 and 7 inclusive");
113 
114  m_bytePos = m_bitPos = 0;
115 
116  int i = m_bitsPerChar;
117  while (i%8 != 0)
118  i += m_bitsPerChar;
119  m_outputBlockSize = i/8;
120 
121  m_outBuf.New(m_outputBlockSize);
122 }
123 
124 size_t BaseN_Decoder::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
125 {
126  FILTER_BEGIN;
127  while (m_inputPosition < length)
128  {
129  unsigned int value;
130  value = m_lookup[begin[m_inputPosition++]];
131  if (value >= 256)
132  continue;
133 
134  if (m_bytePos == 0 && m_bitPos == 0)
135  memset(m_outBuf, 0, m_outputBlockSize);
136 
137  {
138  int newBitPos = m_bitPos + m_bitsPerChar;
139  if (newBitPos <= 8)
140  m_outBuf[m_bytePos] |= value << (8-newBitPos);
141  else
142  {
143  m_outBuf[m_bytePos] |= value >> (newBitPos-8);
144  m_outBuf[m_bytePos+1] |= value << (16-newBitPos);
145  }
146 
147  m_bitPos = newBitPos;
148  while (m_bitPos >= 8)
149  {
150  m_bitPos -= 8;
151  ++m_bytePos;
152  }
153  }
154 
155  if (m_bytePos == m_outputBlockSize)
156  {
157  FILTER_OUTPUT(1, m_outBuf, m_outputBlockSize, 0);
158  m_bytePos = m_bitPos = 0;
159  }
160  }
161  if (messageEnd)
162  {
163  FILTER_OUTPUT(2, m_outBuf, m_bytePos, messageEnd);
164  m_bytePos = m_bitPos = 0;
165  }
166  FILTER_END_NO_MESSAGE_END;
167 }
168 
169 void BaseN_Decoder::InitializeDecodingLookupArray(int *lookup, const byte *alphabet, unsigned int base, bool caseInsensitive)
170 {
171  std::fill(lookup, lookup+256, -1);
172 
173  for (unsigned int i=0; i<base; i++)
174  {
175  if (caseInsensitive && isalpha(alphabet[i]))
176  {
177  assert(lookup[toupper(alphabet[i])] == -1);
178  lookup[toupper(alphabet[i])] = i;
179  assert(lookup[tolower(alphabet[i])] == -1);
180  lookup[tolower(alphabet[i])] = i;
181  }
182  else
183  {
184  assert(lookup[alphabet[i]] == -1);
185  lookup[alphabet[i]] = i;
186  }
187  }
188 }
189 
190 void Grouper::IsolatedInitialize(const NameValuePairs &parameters)
191 {
192  m_groupSize = parameters.GetIntValueWithDefault(Name::GroupSize(), 0);
193  ConstByteArrayParameter separator, terminator;
194  if (m_groupSize)
195  parameters.GetRequiredParameter("Grouper", Name::Separator(), separator);
196  else
197  parameters.GetValue(Name::Separator(), separator);
198  parameters.GetValue(Name::Terminator(), terminator);
199 
200  m_separator.Assign(separator.begin(), separator.size());
201  m_terminator.Assign(terminator.begin(), terminator.size());
202  m_counter = 0;
203 }
204 
205 size_t Grouper::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
206 {
207  FILTER_BEGIN;
208  if (m_groupSize)
209  {
210  while (m_inputPosition < length)
211  {
212  if (m_counter == m_groupSize)
213  {
214  FILTER_OUTPUT(1, m_separator, m_separator.size(), 0);
215  m_counter = 0;
216  }
217 
218  size_t len;
219  FILTER_OUTPUT2(2, len = STDMIN(length-m_inputPosition, m_groupSize-m_counter),
220  begin+m_inputPosition, len, 0);
221  m_inputPosition += len;
222  m_counter += len;
223  }
224  }
225  else
226  FILTER_OUTPUT(3, begin, length, 0);
227 
228  if (messageEnd)
229  {
230  FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd);
231  m_counter = 0;
232  }
233  FILTER_END_NO_MESSAGE_END
234 }
235 
236 NAMESPACE_END
237 
238 #endif