@@ -149,14 +149,22 @@ std::string Base64::toBase64(const std::vector<std::uint8_t>& bytes)
149
149
return result;
150
150
}
151
151
152
- bool Base64::compareBase64 (
152
+ Base64::Comparison Base64::compareBase64 (
153
153
const std::vector<std::uint8_t >& bytes, std::string_view maybeEncoded) noexcept
154
154
{
155
- if (bytes.empty () || maybeEncoded. empty () )
155
+ if (bytes.empty ())
156
156
{
157
- return bytes.empty () && maybeEncoded.empty ();
157
+ if (maybeEncoded.empty ())
158
+ {
159
+ return Comparison::EqualTo;
160
+ }
161
+ }
162
+ else if (maybeEncoded.empty ())
163
+ {
164
+ return Comparison::GreaterThan;
158
165
}
159
166
167
+ auto result = Comparison::EqualTo;
160
168
auto itr = bytes.cbegin ();
161
169
const auto itrEnd = bytes.cend ();
162
170
@@ -171,18 +179,34 @@ bool Base64::compareBase64(
171
179
if (((a | b | c | d) & 0xC0 ) != 0 )
172
180
{
173
181
// Invalid Base64 characters
174
- return false ;
182
+ return Comparison::InvalidBase64 ;
175
183
}
176
184
177
- const uint32_t segment = (static_cast <uint32_t >(a) << 18 ) | (static_cast <uint32_t >(b) << 12 )
178
- | (static_cast <uint32_t >(c) << 6 ) | static_cast <uint32_t >(d);
179
-
180
- if (itr == itrEnd || *itr++ != static_cast <std::uint8_t >((segment & 0xFF0000 ) >> 16 )
181
- || itr == itrEnd || *itr++ != static_cast <std::uint8_t >((segment & 0xFF00 ) >> 8 )
182
- || itr == itrEnd || *itr++ != static_cast <std::uint8_t >(segment & 0xFF ))
185
+ if (Comparison::EqualTo == result)
183
186
{
184
- // Decoded bytes did not match
185
- return false ;
187
+ const uint32_t segment = (static_cast <uint32_t >(a) << 18 )
188
+ | (static_cast <uint32_t >(b) << 12 ) | (static_cast <uint32_t >(c) << 6 )
189
+ | static_cast <uint32_t >(d);
190
+ const std::array decoded { static_cast <std::uint8_t >((segment & 0xFF0000 ) >> 16 ),
191
+ static_cast <std::uint8_t >((segment & 0xFF00 ) >> 8 ),
192
+ static_cast <std::uint8_t >(segment & 0xFF ) };
193
+
194
+ for (auto value : decoded)
195
+ {
196
+ if (itr == itrEnd)
197
+ {
198
+ result = Comparison::LessThan;
199
+ break ;
200
+ }
201
+
202
+ if (*itr != value)
203
+ {
204
+ result = *itr < value ? Comparison::LessThan : Comparison::GreaterThan;
205
+ break ;
206
+ }
207
+
208
+ ++itr;
209
+ }
186
210
}
187
211
188
212
maybeEncoded = maybeEncoded.substr (4 );
@@ -199,55 +223,81 @@ bool Base64::compareBase64(
199
223
if (((a | b | c) & 0xC0 ) != 0 || (c & 0x3 ) != 0 )
200
224
{
201
225
// Invalid Base64 characters or padding
202
- return false ;
226
+ return Comparison::InvalidBase64 ;
203
227
}
204
228
205
229
const uint16_t segment = (static_cast <uint16_t >(a) << 10 ) | (static_cast <uint16_t >(b) << 4 )
206
230
| (static_cast <uint16_t >(c) >> 2 );
231
+ const std::array decoded { static_cast <std::uint8_t >((segment & 0xFF00 ) >> 8 ),
232
+ static_cast <std::uint8_t >(segment & 0xFF ) };
207
233
208
234
if (triplet)
209
235
{
210
- if (itr == itrEnd || *itr++ != static_cast <std::uint8_t >((segment & 0xFF00 ) >> 8 )
211
- || itr == itrEnd || *itr++ != static_cast <std::uint8_t >(segment & 0xFF ))
236
+ if (Comparison::EqualTo == result)
212
237
{
213
- // Decoded bytes did not match
214
- return false ;
238
+ for (auto value : decoded)
239
+ {
240
+ if (itr == itrEnd)
241
+ {
242
+ result = Comparison::LessThan;
243
+ break ;
244
+ }
245
+
246
+ if (*itr != value)
247
+ {
248
+ result = *itr < value ? Comparison::LessThan : Comparison::GreaterThan;
249
+ break ;
250
+ }
251
+
252
+ ++itr;
253
+ }
215
254
}
216
255
217
256
maybeEncoded = maybeEncoded.substr (3 );
218
257
}
219
258
else
220
259
{
221
- if ((segment & 0xFF ) != 0 )
260
+ if (decoded[ 1 ] != 0 )
222
261
{
223
262
// Invalid padding
224
- return false ;
263
+ return Comparison::InvalidBase64 ;
225
264
}
226
265
227
- if (itr == itrEnd || *itr++ != static_cast <std:: uint8_t >((segment & 0xFF00 ) >> 8 ) )
266
+ if (Comparison::EqualTo == result )
228
267
{
229
- // Decoded byte did not match
230
- return false ;
268
+ if (itr == itrEnd)
269
+ {
270
+ result = Comparison::LessThan;
271
+ }
272
+ else if (*itr != decoded[0 ])
273
+ {
274
+ result = *itr < decoded[0 ] ? Comparison::LessThan : Comparison::GreaterThan;
275
+ }
276
+
277
+ ++itr;
231
278
}
232
279
233
280
maybeEncoded = maybeEncoded.substr (2 );
234
281
}
235
282
}
236
283
237
- // We should reach the end of the byte vector
238
- if (itr != itrEnd)
239
- {
240
- return false ;
241
- }
242
-
243
284
// Make sure anything that's left is 0 - 2 characters of padding
244
285
if ((maybeEncoded.size () > 0 && padding != maybeEncoded[0 ])
245
286
|| (maybeEncoded.size () > 1 && padding != maybeEncoded[1 ]) || maybeEncoded.size () > 2 )
246
287
{
247
- return false ;
288
+ return Comparison::InvalidBase64 ;
248
289
}
249
290
250
- return true ;
291
+ if (Comparison::EqualTo == result)
292
+ {
293
+ // We should reach the end of the byte vector
294
+ if (itr != itrEnd)
295
+ {
296
+ result = Comparison::GreaterThan;
297
+ }
298
+ }
299
+
300
+ return result;
251
301
}
252
302
253
303
bool Base64::validateBase64 (std::string_view maybeEncoded) noexcept
0 commit comments