Index: components/base32/base32.cc |
diff --git a/components/base32/base32.cc b/components/base32/base32.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..720842f22560809fe27d25a72d5577575dab98c3 |
--- /dev/null |
+++ b/components/base32/base32.cc |
@@ -0,0 +1,59 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "components/base32/base32.h" |
+ |
+#include <stddef.h> |
+#include <algorithm> |
+ |
+namespace base32 { |
+ |
+namespace { |
+const char kEncoding[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; |
+} // namespace |
+ |
+void Base32Encode(base::StringPiece input, |
+ Base32EncodePolicy policy, |
+ std::string* output) { |
+ output->clear(); |
+ |
+ // Transform 5 input bytes into 8 output bytes at a time. |
+ // Based on the encoding process described in RFC4648, section 6. |
+ for (size_t input_offset = 0; input_offset < input.size(); |
+ input_offset += 5) { |
+ // Bits of input left to encode. |
+ size_t bits_remaining = |
+ std::min(size_t(5), input.size() - input_offset) * 8; |
+ // A buffer for up to 40 bits of input that is consumed 5 bits at a time. |
+ // 40 bits is used because it is the lowest common multiple of 5 and 8. |
+ uint64_t input_group = 0; |
+ |
+ // Load 8 bits at a time into the buffer. |
+ // Can't simply memcpy because of endianness. |
+ for (size_t i = 0; i < bits_remaining / 8; ++i) { |
+ input_group <<= 8; |
+ input_group |= static_cast<uint8_t>(input[input_offset + i]); |
+ } |
+ // Shift the bits we've set to start at the MSB, for ease of access. |
+ input_group <<= (64 - bits_remaining); |
+ |
+ // Output the |input_group| as up to 8 bytes in base32. |
+ // If we run out of bits, padding will make up the remaining bytes |
+ // (unless |policy| dictates otherwise). |
+ for (size_t output_count = 0; output_count < 8; ++output_count) { |
+ if (bits_remaining == 0) { |
+ if (policy == Base32EncodePolicy::INCLUDE_PADDING) |
+ output->append(8 - output_count, '='); |
+ break; |
+ } |
+ // Encode the first 5 bits, then shift them out of the buffer. |
+ output->push_back(kEncoding[input_group >> 59]); |
+ input_group <<= 5; |
+ // Subtract 5 bits, or however many are left, whichever is smaller. |
+ bits_remaining -= (bits_remaining >= 5) ? 5 : bits_remaining; |
+ } |
+ } |
+} |
+ |
+} // namespace base32 |