diff --git a/src/core_write.cpp b/src/core_write.cpp --- a/src/core_write.cpp +++ b/src/core_write.cpp @@ -53,16 +53,20 @@ } if (vch.size() > 0) { - ret += strprintf("0x%x 0x%x ", HexStr(it2, it - vch.size()), - HexStr(it - vch.size(), it)); + ret += strprintf( + "0x%x 0x%x ", + HexStr(std::vector(it2, it - vch.size())), + HexStr(std::vector(it - vch.size(), it))); } else { - ret += strprintf("0x%x ", HexStr(it2, it)); + ret += + strprintf("0x%x ", HexStr(std::vector(it2, it))); } continue; } - ret += strprintf("0x%x ", HexStr(it2, script.end())); + ret += + strprintf("0x%x ", HexStr(std::vector(it2, script.end()))); break; } diff --git a/src/net.cpp b/src/net.cpp --- a/src/net.cpp +++ b/src/net.cpp @@ -763,9 +763,9 @@ LogPrint( BCLog::NET, "CHECKSUM ERROR (%s, %u bytes), expected %s was %s\n", SanitizeString(msg.m_command), msg.m_message_size, - HexStr(hash.begin(), hash.begin() + CMessageHeader::CHECKSUM_SIZE), - HexStr(hdr.pchChecksum, - hdr.pchChecksum + CMessageHeader::CHECKSUM_SIZE)); + HexStr(Span(hash.begin(), + hash.begin() + CMessageHeader::CHECKSUM_SIZE)), + HexStr(hdr.pchChecksum)); } // store receive time diff --git a/src/rpc/avalanche.cpp b/src/rpc/avalanche.cpp --- a/src/rpc/avalanche.cpp +++ b/src/rpc/avalanche.cpp @@ -200,7 +200,7 @@ CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << proof; - return HexStr(ss.begin(), ss.end()); + return HexStr(ss); } void RegisterAvalancheRPCCommands(CRPCTable &t) { diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -1611,7 +1611,7 @@ if (complete && extract) { ssTx << mtx; - result_str = HexStr(ssTx.str()); + result_str = HexStr(ssTx); result.pushKV("hex", result_str); } else { ssTx << psbtx; diff --git a/src/rpc/request.cpp b/src/rpc/request.cpp --- a/src/rpc/request.cpp +++ b/src/rpc/request.cpp @@ -77,8 +77,7 @@ const size_t COOKIE_SIZE = 32; uint8_t rand_pwd[COOKIE_SIZE]; GetRandBytes(rand_pwd, COOKIE_SIZE); - std::string cookie = - COOKIEAUTH_USER + ":" + HexStr(rand_pwd, rand_pwd + COOKIE_SIZE); + std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd); /** * the umask determines what permissions are used to create this file - diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -229,9 +229,7 @@ std::unique_ptr m_provider; std::string OriginString() const { - return HexStr(std::begin(m_origin.fingerprint), - std::end(m_origin.fingerprint)) + - FormatHDKeypath(m_origin.path); + return HexStr(m_origin.fingerprint) + FormatHDKeypath(m_origin.path); } public: diff --git a/src/test/crypto_tests.cpp b/src/test/crypto_tests.cpp --- a/src/test/crypto_tests.cpp +++ b/src/test/crypto_tests.cpp @@ -280,7 +280,7 @@ initial_key_material.size(), salt_stringified); uint8_t out[32]; hkdf32.Expand32(info_stringified, out); - BOOST_CHECK(HexStr(out, out + 32) == okm_check_hex); + BOOST_CHECK(HexStr(out) == okm_check_hex); } static std::string LongTestString() { diff --git a/src/test/settings_tests.cpp b/src/test/settings_tests.cpp --- a/src/test/settings_tests.cpp +++ b/src/test/settings_tests.cpp @@ -272,8 +272,7 @@ uint8_t out_sha_bytes[CSHA256::OUTPUT_SIZE]; out_sha.Finalize(out_sha_bytes); - std::string out_sha_hex = - HexStr(std::begin(out_sha_bytes), std::end(out_sha_bytes)); + std::string out_sha_hex = HexStr(out_sha_bytes); // If check below fails, should manually dump the results with: // diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -100,43 +100,22 @@ } BOOST_AUTO_TEST_CASE(util_HexStr) { - BOOST_CHECK_EQUAL(HexStr(ParseHex_expected, - ParseHex_expected + sizeof(ParseHex_expected)), + BOOST_CHECK_EQUAL(HexStr(ParseHex_expected), "04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0" "ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d" "578a4c702b6bf11d5f"); - BOOST_CHECK_EQUAL(HexStr(ParseHex_expected + sizeof(ParseHex_expected), - ParseHex_expected + sizeof(ParseHex_expected)), + BOOST_CHECK_EQUAL(HexStr(Span( + ParseHex_expected + sizeof(ParseHex_expected), + ParseHex_expected + sizeof(ParseHex_expected))), ""); - BOOST_CHECK_EQUAL(HexStr(ParseHex_expected, ParseHex_expected), ""); - - std::vector ParseHex_vec(ParseHex_expected, ParseHex_expected + 5); - - BOOST_CHECK_EQUAL(HexStr(ParseHex_vec.rbegin(), ParseHex_vec.rend()), - "b0fd8a6704"); - BOOST_CHECK_EQUAL( - HexStr(std::reverse_iterator(ParseHex_expected), - std::reverse_iterator(ParseHex_expected)), - ""); + HexStr(Span(ParseHex_expected, ParseHex_expected)), ""); - BOOST_CHECK_EQUAL( - HexStr(std::reverse_iterator(ParseHex_expected + 1), - std::reverse_iterator(ParseHex_expected)), - "04"); - - BOOST_CHECK_EQUAL( - HexStr(std::reverse_iterator(ParseHex_expected + 5), - std::reverse_iterator(ParseHex_expected)), - "b0fd8a6704"); + std::vector ParseHex_vec(ParseHex_expected, ParseHex_expected + 5); - BOOST_CHECK_EQUAL( - HexStr(std::reverse_iterator(ParseHex_expected + 65), - std::reverse_iterator(ParseHex_expected)), - "5f1df16b2b704c8a578d0bbaf74d385cde12c11ee50455f3c438ef4c3fbcf649b6de61" - "1feae06279a60939e028a8d65c10b73071a6f16719274855feb0fd8a6704"); + BOOST_CHECK_EQUAL(HexStr(ParseHex_vec), "04678afdb0"); } BOOST_AUTO_TEST_CASE(util_Join) { @@ -1194,8 +1173,7 @@ uint8_t out_sha_bytes[CSHA256::OUTPUT_SIZE]; out_sha.Finalize(out_sha_bytes); - std::string out_sha_hex = - HexStr(std::begin(out_sha_bytes), std::end(out_sha_bytes)); + std::string out_sha_hex = HexStr(out_sha_bytes); // If check below fails, should manually dump the results with: // @@ -1335,8 +1313,7 @@ uint8_t out_sha_bytes[CSHA256::OUTPUT_SIZE]; out_sha.Finalize(out_sha_bytes); - std::string out_sha_hex = - HexStr(std::begin(out_sha_bytes), std::end(out_sha_bytes)); + std::string out_sha_hex = HexStr(out_sha_bytes); // If check below fails, should manually dump the results with: // diff --git a/src/uint256.cpp b/src/uint256.cpp --- a/src/uint256.cpp +++ b/src/uint256.cpp @@ -14,9 +14,11 @@ } template std::string base_blob::GetHex() const { - return HexStr( - std::reverse_iterator(m_data + sizeof(m_data)), - std::reverse_iterator(m_data)); + uint8_t m_data_rev[WIDTH]; + for (int i = 0; i < WIDTH; ++i) { + m_data_rev[i] = m_data[WIDTH - 1 - i]; + } + return HexStr(m_data_rev); } template void base_blob::SetHex(const char *psz) { diff --git a/src/util/strencodings.h b/src/util/strencodings.h --- a/src/util/strencodings.h +++ b/src/util/strencodings.h @@ -10,6 +10,7 @@ #define BITCOIN_UTIL_STRENCODINGS_H #include +#include #include #include @@ -137,21 +138,12 @@ */ NODISCARD bool ParseDouble(const std::string &str, double *out); -template std::string HexStr(const T itbegin, const T itend) { - std::string rv; - static const char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - rv.reserve(std::distance(itbegin, itend) * 2); - for (T it = itbegin; it < itend; ++it) { - uint8_t val = uint8_t(*it); - rv.push_back(hexmap[val >> 4]); - rv.push_back(hexmap[val & 15]); - } - return rv; -} - -template inline std::string HexStr(const T &vch) { - return HexStr(vch.begin(), vch.end()); +/** + * Convert a span of bytes to a lower-case hexadecimal string. + */ +std::string HexStr(const Span s); +inline std::string HexStr(const Span s) { + return HexStr(MakeUCharSpan(s)); } /** diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -648,3 +648,15 @@ str[0] = ToUpper(str.front()); return str; } + +std::string HexStr(const Span s) { + std::string rv; + static constexpr char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + rv.reserve(s.size() * 2); + for (uint8_t v : s) { + rv.push_back(hexmap[v >> 4]); + rv.push_back(hexmap[v & 15]); + } + return rv; +} diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -43,10 +43,7 @@ throw std::runtime_error(strprintf( "BerkeleyBatch: Can't open database %s (duplicates fileid %s " "from %s)", - filename, - HexStr(std::begin(item.second.value), - std::end(item.second.value)), - item.first)); + filename, HexStr(item.second.value), item.first)); } } } diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -32,7 +32,7 @@ std::stringstream ret; for (const uint8_t c : str) { if (c <= 32 || c >= 128 || c == '%') { - ret << '%' << HexStr(&c, &c + 1); + ret << '%' << HexStr(Span(&c, 1)); } else { ret << c; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4462,8 +4462,7 @@ ret.pushKV("hdkeypath", WriteHDKeypath(meta->key_origin.path)); ret.pushKV("hdseedid", meta->hd_seed_id.GetHex()); ret.pushKV("hdmasterfingerprint", - HexStr(meta->key_origin.fingerprint, - meta->key_origin.fingerprint + 4)); + HexStr(meta->key_origin.fingerprint)); } } }