Untitled

mail@pastecode.io avatar
unknown
c_cpp
a year ago
3.8 kB
8
Indexable
Never
#include <iostream>
#include <vector>
#include <string>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <iomanip>

class TreeNode {
public:
    std::string value;
    std::string hashValue;
    TreeNode* left;
    TreeNode* right;

    TreeNode(const std::string& val, const std::string& hash) : value(val), hashValue(hash), left(nullptr), right(nullptr) {}
};

std::string sha256(const std::string &input) {
    unsigned char hash[SHA256_DIGEST_LENGTH];
    EVP_MD_CTX *mdctx = EVP_MD_CTX_new();

    EVP_DigestInit(mdctx, EVP_sha256());
    EVP_DigestUpdate(mdctx, input.c_str(), input.length());
    EVP_DigestFinal(mdctx, hash, NULL);
    EVP_MD_CTX_free(mdctx);

    std::stringstream hashStream;
    hashStream << std::hex << std::setfill('0');
    for (int i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
        hashStream << std::setw(2) << static_cast<int>(hash[i]);
    }

    return hashStream.str();
}

TreeNode* createIntermediateNode(TreeNode* leftNode, TreeNode* rightNode) {
    std::string concatenatedValue = leftNode->value + rightNode->value;  // Concatenate values instead of hash values
    TreeNode* intermediateNode = new TreeNode(concatenatedValue, sha256(concatenatedValue));
    intermediateNode->left = leftNode;
    intermediateNode->right = rightNode;
    return intermediateNode;
}

void duplicateLastNodeIfOdd(std::vector<TreeNode*>& nodes) {
    if (nodes.size() % 2 != 0) {
        nodes.push_back(new TreeNode(nodes.back()->value, nodes.back()->hashValue));
    }
}

void printTree(TreeNode* node, const std::string& prefix, bool isLeft) {
    if (node != nullptr) {
        std::cout << prefix;
        std::cout << (isLeft ? "├──" : "└──");
        std::cout << "Data: " << node->value << " | Hash: " << node->hashValue;
        std::cout << std::endl;

        printTree(node->left, prefix + (isLeft ? "│   " : "    "), true);
        printTree(node->right, prefix + (isLeft ? "│   " : "    "), false);
    }
}

void printTreeVisualizer(TreeNode* node) {
    printTree(node, "", false);
}

int main() {
   std::vector<std::string> inputArray;
    int numInputs;
    
    std::cout << "Enter the number of inputs: ";
    std::cin >> numInputs;

    for (int i = 0; i < numInputs; ++i) {
        std::string input;
        std::cout << "Enter input " << i + 1 << ": ";
        std::cin >> input;
        inputArray.push_back(input);
    }
    int numLeafNodes = inputArray.size();

    std::vector<TreeNode*> leafNodes;

    // Create leaf nodes
    for (const std::string& data : inputArray) {
        TreeNode* leafNode = new TreeNode(data, sha256(data));
        leafNodes.push_back(leafNode);
    }

    std::vector<TreeNode*> intermediateNodes = leafNodes;

    // Construct the tree
    while (intermediateNodes.size() > 1) {
        duplicateLastNodeIfOdd(intermediateNodes);

        std::vector<TreeNode*> newIntermediateNodes;
        for (size_t i = 0; i < intermediateNodes.size(); i += 2) {
            TreeNode* intermediateNode = createIntermediateNode(intermediateNodes[i], intermediateNodes[i + 1]);
            newIntermediateNodes.push_back(intermediateNode);
        }
        intermediateNodes = newIntermediateNodes;
    }

    TreeNode* root = intermediateNodes[0];

    // printf("\nMerkle Root: %s\n", root->hashValue);
    std::cout << "\nMerkle Root: " << root->hashValue << std::endl;
    // Display the tree structure using the visualizer
    std::cout << "Tree Structure:\n\n";
    printTreeVisualizer(root);
    printf("\n");

    // Clean up memory (deallocating nodes)
    for (TreeNode* node : leafNodes) {
        delete node;
    }

    return 0;
}