Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2009-2010 Satoshi Nakamoto2// Copyright (c) 2009-present The Bitcoin Core developers3// Distributed under the MIT software license, see the accompanying4// file COPYING or http://www.opensource.org/licenses/mit-license.php.6/**7* Utilities for converting data from/to strings.8*/9#ifndef BITCOIN_UTIL_STRENCODINGS_H10#define BITCOIN_UTIL_STRENCODINGS_H12#include <span.h>13#include <util/string.h>15#include <array>16#include <bit>17#include <charconv>18#include <cstddef>19#include <cstdint>20#include <functional>21#include <limits>22#include <optional>23#include <span>24#include <string>25#include <string_view>26#include <system_error>27#include <type_traits>28#include <vector>30/** Used by SanitizeString() */31enum SafeChars32{33SAFE_CHARS_DEFAULT, //!< The full set of allowed chars34SAFE_CHARS_UA_COMMENT, //!< BIP-0014 subset35SAFE_CHARS_FILENAME, //!< Chars allowed in filenames36SAFE_CHARS_URI, //!< Chars allowed in URIs (RFC 3986)37};39/**40* Used by ParseByteUnits()41* Lowercase base 100042* Uppercase base 102443*/44enum class ByteUnit : uint64_t {45NOOP = 1ULL,46k = 1000ULL,47K = 1024ULL,48m = 1'000'000ULL,49M = 1ULL << 20,50g = 1'000'000'000ULL,51G = 1ULL << 30,52t = 1'000'000'000'000ULL,53T = 1ULL << 40,54};56/**57* Remove unsafe chars. Safe chars chosen to allow simple messages/URLs/email58* addresses, but avoid anything even possibly remotely dangerous like & or >59* @param[in] str The string to sanitize60* @param[in] rule The set of safe chars to choose (default: least restrictive)61* @return A new string without unsafe chars62*/63std::string SanitizeString(std::string_view str, int rule = SAFE_CHARS_DEFAULT);64/** Parse the hex string into bytes (uint8_t or std::byte). Ignores whitespace. Returns nullopt on invalid input. */65template <typename Byte = std::byte>66std::optional<std::vector<Byte>> TryParseHex(std::string_view str);67/** Like TryParseHex, but returns an empty vector on invalid input. */68template <typename Byte = uint8_t>69std::vector<Byte> ParseHex(std::string_view hex_str)70{71return TryParseHex<Byte>(hex_str).value_or(std::vector<Byte>{});72}73/* Returns true if each character in str is a hex character, and has an even74* number of hex digits.*/75bool IsHex(std::string_view str);76std::optional<std::vector<unsigned char>> DecodeBase64(std::string_view str);77std::string EncodeBase64(std::span<const unsigned char> input);78inline std::string EncodeBase64(std::span<const std::byte> input) { return EncodeBase64(MakeUCharSpan(input)); }79inline std::string EncodeBase64(std::string_view str) { return EncodeBase64(MakeUCharSpan(str)); }80std::optional<std::vector<unsigned char>> DecodeBase32(std::string_view str);82/**83* Base32 encode.84* If `pad` is true, then the output will be padded with '=' so that its length85* is a multiple of 8.86*/87std::string EncodeBase32(std::span<const unsigned char> input, bool pad = true);89/**90* Base32 encode.91* If `pad` is true, then the output will be padded with '=' so that its length92* is a multiple of 8.93*/94std::string EncodeBase32(std::string_view str, bool pad = true);96/**97* Splits socket address string into host string and port value.98* Validates port value.99*100* @param[in] in The socket address string to split.101* @param[out] portOut Port-portion of the input, if found and parsable.102* @param[out] hostOut Host-portion of the input, if found.103* @return true if port-portion is absent or within its allowed range, otherwise false104*/105bool SplitHostPort(std::string_view in, uint16_t& portOut, std::string& hostOut);107// LocaleIndependentAtoi is provided for backwards compatibility reasons.108//109// New code should use ToIntegral.110//111// The goal of LocaleIndependentAtoi is to replicate the defined behaviour of112// std::atoi as it behaves under the "C" locale, and remove some undefined113// behavior. If the parsed value is bigger than the integer type's maximum114// value, or smaller than the integer type's minimum value, std::atoi has115// undefined behavior, while this function returns the maximum or minimum116// values, respectively.117template <typename T>118T LocaleIndependentAtoi(std::string_view str)119{120static_assert(std::is_integral_v<T>);121T result;122// Emulate atoi(...) handling of white space and leading +/-.123std::string_view s = util::TrimStringView(str);124if (!s.empty() && s[0] == '+') {125if (s.length() >= 2 && s[1] == '-') {126return 0;127}128s = s.substr(1);129}130auto [_, error_condition] = std::from_chars(s.data(), s.data() + s.size(), result);131if (error_condition == std::errc::result_out_of_range) {132if (s.length() >= 1 && s[0] == '-') {133// Saturate underflow, per strtoll's behavior.134return std::numeric_limits<T>::min();135} else {136// Saturate overflow, per strtoll's behavior.137return std::numeric_limits<T>::max();138}139} else if (error_condition != std::errc{}) {140return 0;141}142return result;143}145/**146* Tests if the given character is a decimal digit.147* @param[in] c character to test148* @return true if the argument is a decimal digit; otherwise false.149*/150constexpr bool IsDigit(char c)151{152return c >= '0' && c <= '9';153}155/**156* Tests if the given character is a whitespace character. The whitespace characters157* are: space, form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal158* tab ('\t'), and vertical tab ('\v').159*160* This function is locale independent. Under the C locale this function gives the161* same result as std::isspace.162*163* @param[in] c character to test164* @return true if the argument is a whitespace character; otherwise false165*/166constexpr inline bool IsSpace(char c) noexcept {167return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';168}170/**171* Convert string to integral type T. Leading whitespace, a leading +, or any172* trailing character fail the parsing. The required format expressed as regex173* is `-?[0-9]+` by default (or `-?[0-9a-fA-F]+` if base = 16).174* The minus sign is only permitted for signed integer types.175*176* @returns std::nullopt if the entire string could not be parsed, or if the177* parsed value is not in the range representable by the type T.178*/179template <typename T>180std::optional<T> ToIntegral(std::string_view str, size_t base = 10)181{182static_assert(std::is_integral_v<T>);183T result;184const auto [first_nonmatching, error_condition] = std::from_chars(str.data(), str.data() + str.size(), result, base);185if (first_nonmatching != str.data() + str.size() || error_condition != std::errc{}) {186return std::nullopt;187}188return result;189}191/**192* Format a paragraph of text to a fixed width, adding spaces for193* indentation to any added line.194*/195std::string FormatParagraph(std::string_view in, size_t width = 79, size_t indent = 0);197/**198* Timing-attack-resistant comparison.199* Takes time proportional to length200* of first argument.201*/202template <typename T>203bool TimingResistantEqual(const T& a, const T& b)204{205if (b.size() == 0) return a.size() == 0;206size_t accumulator = a.size() ^ b.size();207for (size_t i = 0; i < a.size(); i++)208accumulator |= size_t(a[i] ^ b[i%b.size()]);209return accumulator == 0;210}212/** Parse number as fixed point according to JSON number syntax.213* @returns true on success, false on error.214* @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger.215*/216[[nodiscard]] bool ParseFixedPoint(std::string_view, int decimals, int64_t *amount_out);218/** Convert from one power-of-2 number base to another. */219template <int frombits, int tobits, bool pad, typename O, typename It, typename I = std::identity>220bool ConvertBits(O outfn, It it, It end, I infn = {})221{222size_t acc = 0;223size_t bits = 0;224constexpr size_t maxv = (1 << tobits) - 1;225constexpr size_t max_acc = (1 << (frombits + tobits - 1)) - 1;226while (it != end) {227int v = infn(*it);228if (v < 0) return false;229acc = ((acc << frombits) | v) & max_acc;230bits += frombits;231while (bits >= tobits) {232bits -= tobits;233outfn((acc >> bits) & maxv);234}235++it;236}237if (pad) {238if (bits) outfn((acc << (tobits - bits)) & maxv);239} else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) {240return false;241}242return true;243}245/**246* Converts the given character to its lowercase equivalent.247* This function is locale independent. It only converts uppercase248* characters in the standard 7-bit ASCII range.249* This is a feature, not a limitation.250*
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.