size_t i = 0; /* Avoid underflow * Not len - i >= 3 */ for (; len >= 3 + i; ) { text.push_back(GetBase64Char(GetBase64Index1(binary))); text.push_back(GetBase64Char(GetBase64Index2(binary))); text.push_back(GetBase64Char(GetBase64Index3(binary))); text.push_back(GetBase64Char(GetBase64Index4(binary))); binary += 3; i += 3; written += 4; if (newline && ((written & 63) == 0)) text.push_back('\n'); } /* | x..x | xx | * | 3n i len | * padding = 3 - left = 3 - (len - i) */ int padding = 3 - (len - i); assert(padding >= 0 && padding <= 3); if (padding == 1) { text.push_back(GetBase64Char(GetBase64Index1(binary))); text.push_back(GetBase64Char(GetBase64Index2(binary))); text.push_back(GetBase64Char(GetBase64IndexPadding1(binary))); text.push_back('='); } elseif (padding == 2) { text.push_back(GetBase64Char(GetBase64Index1(binary))); text.push_back(GetBase64Char(GetBase64IndexPadding2(binary))); text.push_back('='); text.push_back('='); } // The last new line don't put only when // the new line has been put, i.e., // the old written % 64 == 0, and the data is empty if (newline && len > 0 && ((written & 63) != 0)) text.push_back('\n'); }
if (((len - new_line_count) & 3) != 0) return BE_INVALID_LENGTH;
// We can compute the size of decoded content raw.reserve(size_t((len - new_line_count) * (3.0/4)));
char ch1, ch2, ch3, ch4;
// Remove the last newline character if (newline) len--; // Handling the last four ascii specially constsize_t end = text[len-1] == '=' ? len - 4 : len;
for (size_t i = 0; i < end;) { // Omit the newline character ch1 = GetBase64(text[i++]); ch2 = GetBase64(text[i++]); ch3 = GetBase64(text[i++]); ch4 = GetBase64(text[i++]); if (ch1 == -1 || ch2 == -1 || ch3 == -1 || ch4 == -1) { fprintf(stderr, "i = %zu, ch1 = %c, ch2 = %c, ch3 = %c, ch4 = %c\n", i, text[i-4], text[i-3], text[i-2], text[i-1]); return BE_INVALID_ENCODING; } raw.push_back(GetBase256_1(ch1, ch2)); raw.push_back(GetBase256_2(ch2, ch3)); raw.push_back(GetBase256_3(ch3, ch4));
for file in $(find raw-files -type f -print); do echo"file: $file" echo"*** encode test ***" ./encode <$file >x0 openssl enc -e -base64 <$file >x1 if ! cmp x0 x1; then exit 1 fi echo"*** encode test end ***"
echo"*** decode test ***" ./decode <x0 >dx0 openssl enc -d -base64 <x1 >dx1 cmp dx0 dx1 if ! cmp x0 x1; then exit 1 fi echo"*** decode test end ***" done
echo echo"*** All tests pass ***" echo
echo"Remove files used for tests" rm x0 x1 dx0 dx1 echo"Remove successfully"