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

Code before:
 */
std::array<uint32_t, 8> compute_hash(const std::string &input) {
    // Initialize array of hash values with first 32 bits of the fractional
    // parts of the square roots of the first 8 primes 2..19
    std::array<uint32_t, 8> hash = {0x6A09E667, 0xBB67AE85, 0x3C6EF372,
                                    0xA54FF53A, 0x510E527F, 0x9B05688C,
                                    0x1F83D9AB, 0x5BE0CD19};

    // Process message in successive 512-bit (64-byte) chunks
    for (size_t i = 0; i < compute_padded_size(input.length()); i += 64) {
        modify_hash(hash, create_message_schedule_array(input, i));
    }

    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::stringstream ss;
    for (size_t i = 0; i < 8; ++i) {
        for (size_t j = 0; j < 4; ++j) {
            uint32_t byte = extract_byte<uint32_t>(hash[i], 3 - j);
            ss << std::hex << std::setfill('0') << std::setw(2) << byte;
        }
    }
    return ss.str();
}

/**
 * @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) {
    return hash_to_string(compute_hash(input));
}
}  // namespace sha256
}  // namespace hashing

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

Review comment (refactor):
```suggestion
            const uint32_t byte = extract_byte<uint32_t>(hash[i], 3 - j);
```

Code after:
                                                       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;
    }

    return blocks;
}

/**
 * @brief Computes the final hash value
 * @param input Input string
 * @return std::string The final hash value
 */
std::string sha256(const std::string &input) {
    Hash h;
    // Process message in successive 512-bit (64-byte) chunks
    for (size_t byte_num = 0; byte_num < compute_padded_size(input.length());
         byte_num += 64) {
        h.update(create_message_schedule_array(input, byte_num));
    }
    return h.to_string();
}
}  // namespace sha256
}  // namespace hashing

/**
 * @brief Self-test implementations
 * @returns void