inline data_chunk operator +(data_slice a, data_slice b) { data_chunk out; out.reserve(a.size() + b.size()); out.insert(out.end(), a.begin(), a.end()); out.insert(out.end(), b.begin(), b.end()); return out; }
bool verify_checksum(data_slice data) { if (data.size() < checksum_size) return false; data_slice body(data.begin(), data.end() - checksum_size); auto checksum = from_little_endian_unsafe<uint32_t>(data.end() - checksum_size); return bitcoin_checksum(body) == checksum; }
binary_type::binary_type(size_type size, data_slice blocks) { // Copy blocks blocks_.resize(blocks.size()); std::copy(blocks.begin(), blocks.end(), blocks_.begin()); // Pad with 00 for safety. while (blocks_.size() * bits_per_block < size) blocks_.push_back(0x00); resize(size); }
bool unwrap(uint8_t& version, data_chunk& payload, uint32_t& checksum, data_slice wrapped) { constexpr size_t version_length = sizeof(version); constexpr size_t checksum_length = sizeof(checksum); // guard against insufficient buffer length if (wrapped.size() < version_length + checksum_length) return false; if (!verify_checksum(wrapped)) return false; // set return values version = wrapped.data()[0]; payload = data_chunk(wrapped.begin() + version_length, wrapped.end() - checksum_length); const auto checksum_start = wrapped.end() - checksum_length; auto deserial = make_deserializer(checksum_start, wrapped.end()); checksum = deserial.read_4_bytes(); return true; }
std::string encode_base58(data_slice unencoded) { size_t leading_zeros = count_leading_zeros(unencoded); // size = log(256) / log(58), rounded up. const size_t number_nonzero = unencoded.size() - leading_zeros; const size_t indexes_size = number_nonzero * 138 / 100 + 1; // Allocate enough space in big-endian base58 representation. data_chunk indexes(indexes_size); // Process the bytes. for (auto it = unencoded.begin() + leading_zeros; it != unencoded.end(); ++it) { pack_value(indexes, *it); } // Skip leading zeroes in base58 result. auto first_nonzero = search_first_nonzero(indexes); // Translate the result into a string. std::string encoded; const size_t estimated_size = leading_zeros + (indexes.end() - first_nonzero); encoded.reserve(estimated_size); encoded.assign(leading_zeros, '1'); // Set actual main bytes. for (auto it = first_nonzero; it != indexes.end(); ++it) { const size_t index = *it; encoded += base58_chars[index]; } return encoded; }
/** * Shoves data into a std::string object. */ std::string to_string(data_slice data) { return std::string(data.begin(), data.end()); }