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