C++ Library to handle BagIt structures. BagIt is a standard format to create transfer packages for digital preservation purposes. See https://en.wikipedia.org/wiki/BagIt for details http://andreas-romeyke.de
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
4.2 KiB

// Copyright (C) 2018 Andreas Romeyke (art1@andreas-romeyke.de), 2018.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include "checksum.hpp"
#include <string>
string string_of_algorithm( checksum_algorithms alg) {
switch( alg ) {
case md5: return string("md5");
case sha1: return string("sha1");
case sha256: return string("sha256");
case sha512: return string("sha512");
}
return string("");
}
string Checksum::checksum_of_file(const string& filepath, checksum_algorithms alg) {
ifstream file (filepath, ios::ate);
stringstream hex_result;
// log << "processing file '" << filepath << "'" << endl;
if (file.is_open() ) {
ifstream::pos_type fileSize;
unsigned char * memBlock;
fileSize = file.tellg();
memBlock = new unsigned char[fileSize];
file.seekg(0,ios::beg);
file.read(reinterpret_cast<char*>(memBlock), fileSize);
switch ( alg ) {
case md5: {
unsigned char result[MD5_DIGEST_LENGTH];
MD5(memBlock, fileSize, result);
for (unsigned char i : result) {
hex_result<< hex << setw(2) << setfill('0') << static_cast<int>( i);
}
break;
}
case sha1: {
unsigned char result[SHA_DIGEST_LENGTH];
SHA1(memBlock, fileSize, result);
for (unsigned char i : result) {
hex_result<< hex << setw(2) << setfill('0') << static_cast<int>( i);
}
break;
}
case sha256: {
unsigned char result[SHA256_DIGEST_LENGTH];
SHA256( memBlock, fileSize, result);
for (unsigned char i : result) {
hex_result<< hex << setw(2) << setfill('0') << static_cast<int>( i);
}
break;
}
case sha512: {
unsigned char result[SHA512_DIGEST_LENGTH];
SHA512( memBlock, fileSize, result);
for (unsigned char i : result) {
hex_result<< hex << setw(2) << setfill('0') << static_cast<int>( i);
}
break;
}
}
delete[] memBlock;
// log << "# # CHECKSUM for filepath '" << filepath << "' " << hex_result.str() << endl;
file.close();
} else {
log << "file '"<< filepath << "' could not be opened" << endl;
}
return hex_result.str();
}
oxum_t Checksum::oxum_of_file(const string& filepath) {
ifstream file (filepath, ios::ate);
oxum_t oxum{};
//log << "processing file '" << filepath << "'" << endl;
if (file.is_open() ) {
ifstream::pos_type fileSize;
fileSize = file.tellg();
oxum.octetcount = fileSize;
oxum.streamcount = 1;
file.close();
} else {
log << "file '"<< filepath << "' could not be opened" << endl;
}
return oxum;
}
oxum_t Checksum::oxum_of_filelist( list<string> files) {
oxum_t oxum{};
oxum.octetcount=0;
oxum.streamcount=0;
list<string>::iterator i;
for (i=files.begin(); i!= files.end(); ++i) {
oxum_t tmp = this->oxum_of_file( *i );
oxum.octetcount+= tmp.octetcount;
oxum.streamcount+= tmp.streamcount;
}
return oxum;
}
void Checksum::get_logstream( stringstream & log ) {
log << this->log.rdbuf();
}
void Checksum::reset_logstream() {
this->log.str(std::string());
}
// vim: set tabstop=4 softtabstop=0 expandtab shiftwidth=4 smarttab