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 ¶meters) |
---|
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 | |
---|
115 | void BaseN_Decoder::IsolatedInitialize(const NameValuePairs ¶meters) |
---|
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 | |
---|
199 | void Grouper::IsolatedInitialize(const NameValuePairs ¶meters) |
---|
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 |
---|