1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
int file_sha256_tree(FILE *f) {
long fSz;
const long cZero = 0L;
ldiv_t fChunks;
fseek(f, 0, SEEK_END);
fSz = ftell(f);
fseek(f, 0, SEEK_SET);
//
fChunks = div(fSz, oneMB);
if (fChunks.rem > 0) {
fChunks.quot++;
}
if (fChunks.quot == cZero) {
file_sha256(f);
}
byteVoV chunkHashes;
//
byte hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
byte *buffer = (byte*) malloc(oneMB);
int bytesRead = 0;
int idx = 0;
while ((bytesRead = fread(buffer, 1, oneMB, f))) {
SHA256_Init(&sha256);
SHA256_Update(&sha256, buffer, bytesRead);
SHA256_Final(hash, &sha256);
//chunkHashes[idx].assign(hash, hash + SHA256_DIGEST_LENGTH);
toAppend.insert(toAppend.begin(),hash[0],SHA256_DIGEST_LENGTH);
chunkHashes.push_back(toAppend);
//chunkHashes[idx].insert(chunkHashes[idx].begin(),hash[0], SHA256_DIGEST_LENGTH);
//
// // // idx++;
}
fclose(f);
free(buffer);
byteVoV L1Hashes = chunkHashes;
while (L1Hashes.size() > 1) {
div_t subLen = div(L1Hashes.size(), cTWO);
if (subLen.rem > 0) {
subLen.quot++;
}
byteVoV L2Hashes;
int j = 0;
for (int i = 0; i < L1Hashes.size(); i = i + 2, j++) {
if (L1Hashes.size() > 1) {
SHA256_Init(&sha256);
byte hshData[SHA256_DIGEST_LENGTH];
copy(L1Hashes[i].begin(), L1Hashes[i].begin() + SHA256_DIGEST_LENGTH, hshData);
SHA256_Update(&sha256, hshData, SHA256_DIGEST_LENGTH);
copy(L1Hashes[i + 1].begin(), L1Hashes[i + 1].begin() + SHA256_DIGEST_LENGTH, hshData);
SHA256_Update(&sha256, hshData, SHA256_DIGEST_LENGTH);
SHA256_Final(hshData, &sha256);
// L2Hashes[j].assign(hshData, hshData + SHA256_DIGEST_LENGTH);
toAppend.insert(toAppend.begin(),hshData[0],SHA256_DIGEST_LENGTH);
L2Hashes.push_back(toAppend);
//
} else {
// L2Hashes[j] = L1Hashes[i];
copy(L2Hashes[j].begin(),L2Hashes[j].end(),L1Hashes[i].begin());
}
}
L1Hashes = L2Hashes;
}
byte rootHash[SHA256_DIGEST_LENGTH];
copy(L1Hashes[0].begin(), L1Hashes[0].begin() + SHA256_DIGEST_LENGTH, rootHash);
hex_convert(rootHash);
//
// cout << fSz << "...." << oneMB << "......" << fChunks.quot << ".....";
return 0;
}
|