Repository: TheAlgorithms/C-Plus-Plus
File: hashing/sha256.cpp (C++)

Code before:
        hash[5] += f;
        hash[6] += g;
        hash[7] += h;
    }

    return hash;
}

/**
 * @brief Convert the hash to a hexadecimal string
 * @param hash Hash array
 * @return std::string Final hash value
 */
std::string hash_to_string(const std::array<uint32_t, 8> &hash) {
    std::string result;
    for (size_t i = 0; i < 8; ++i) {
        for (size_t j = 0; j < 4; ++j) {
            uint32_t byte = (hash[i] >> (24 - j * 8)) & 0xFF;
            std::stringstream ss;
            ss << std::hex << std::setfill('0') << std::setw(2) << byte;
            result += ss.str();
        }
    }

    return result;
}

/**
 * @brief The SHA-256 algorithm
 * @param input The input string to hash
 * @return std::string The final hash value
 */
std::string sha256(const std::string &input) {
    std::array<uint32_t, 8> hash = compute_hash(input);

    std::string result = hash_to_string(hash);

    return result;
}
}  // namespace sha256
}  // namespace hashing

/**
 * @brief Self-test implementations
 * @returns void
 */
static void test() {
    struct TestCase {
        const std::string input;
        const std::string expected_hash;
        TestCase(std::string input, std::string expected_hash)

Review comment (suggestion):
```suggestion
std::string hash_to_string(const std::array<uint32_t, 8> &hash) {
    std::stringstream ss;
    for (size_t i = 0; i < 8; ++i) {
        for (size_t j = 0; j < 4; ++j) {
            uint32_t byte = (hash[i] >> (24 - j * 8)) & 0xFF;
            ss << std::hex << std::setfill('0') << std::setw(2) << byte;
        }
    }
    return ss.str();
}
```

Code after:
    const auto input_size = input.length();
    if (pos < input_size) {
        return input[pos];
    }
    if (pos == input_size) {
        return '\x80';
    }
    const auto padded_input_size = compute_padded_size(input_size);
    if (pos < padded_input_size - 8) {
        return '\x00';
    }
    if (padded_input_size <= pos) {
        throw std::out_of_range("pos is out of range");
    }
    return static_cast<char>(
        extract_byte<size_t>(input_size * 8, padded_input_size - pos - 1));
}

/**
 * @brief Creates the message schedule array
 * @param input Input string
 * @param byte_num Position of the first byte of the chunk
 * @return std::array<uint32_t, 64> Message schedule array
 */
std::array<uint32_t, 64> create_message_schedule_array(const std::string &input,
                                                       const size_t byte_num) {
    std::array<uint32_t, 64> blocks{};

    // Copy chunk into first 16 words of the message schedule array
    for (size_t block_num = 0; block_num < 16; ++block_num) {
        blocks[block_num] =
            (static_cast<uint8_t>(get_char(input, byte_num + block_num * 4))
             << 24) |
            (static_cast<uint8_t>(get_char(input, byte_num + block_num * 4 + 1))
             << 16) |
            (static_cast<uint8_t>(get_char(input, byte_num + block_num * 4 + 2))
             << 8) |
            static_cast<uint8_t>(get_char(input, byte_num + block_num * 4 + 3));
    }

    // Extend the first 16 words into remaining 48 words of the message schedule
    // array
    for (size_t block_num = 16; block_num < 64; ++block_num) {
        const auto s0 = right_rotate(blocks[block_num - 15], 7) ^
                        right_rotate(blocks[block_num - 15], 18) ^
                        (blocks[block_num - 15] >> 3);
        const auto s1 = right_rotate(blocks[block_num - 2], 17) ^
                        right_rotate(blocks[block_num - 2], 19) ^
                        (blocks[block_num - 2] >> 10);
        blocks[block_num] =
            blocks[block_num - 16] + s0 + blocks[block_num - 7] + s1;