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.

120 lines
3.9 KiB

  1. // Copyright (C) 2018 Andreas Romeyke (art1@andreas-romeyke.de), 2018.
  2. //
  3. // This program is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  15. #include <iostream>
  16. #include <iomanip>
  17. #include <fstream>
  18. #include <sstream>
  19. #include "checksum.hpp"
  20. #include <string>
  21. string string_of_algorithm( checksum_algorithms alg) {
  22. switch( alg ) {
  23. case md5: return string("md5");
  24. case sha1: return string("sha1");
  25. case sha256: return string("sha256");
  26. }
  27. return string("");
  28. }
  29. string Checksum::checksum_of_file(const string& filepath, checksum_algorithms alg) {
  30. ifstream file (filepath, ios::ate);
  31. stringstream hex_result;
  32. // log << "processing file '" << filepath << "'" << endl;
  33. if (file.is_open() ) {
  34. ifstream::pos_type fileSize;
  35. unsigned char * memBlock;
  36. fileSize = file.tellg();
  37. memBlock = new unsigned char[fileSize];
  38. if (nullptr != memBlock) {
  39. file.seekg(0,ios::beg);
  40. file.read(reinterpret_cast<char*>(memBlock), fileSize);
  41. switch ( alg ) {
  42. case md5: {
  43. unsigned char result[MD5_DIGEST_LENGTH];
  44. MD5(memBlock, fileSize, result);
  45. for (unsigned char i : result) {
  46. hex_result<< hex << setw(2) << setfill('0') << static_cast<int>( i);
  47. }
  48. break;
  49. }
  50. case sha1: {
  51. unsigned char result[SHA_DIGEST_LENGTH];
  52. SHA1(memBlock, fileSize, result);
  53. for (unsigned char i : result) {
  54. hex_result<< hex << setw(2) << setfill('0') << static_cast<int>( i);
  55. }
  56. break;
  57. }
  58. case sha256: {
  59. unsigned char result[SHA_DIGEST_LENGTH];
  60. SHA256( memBlock, fileSize, result);
  61. for (unsigned char i : result) {
  62. hex_result<< hex << setw(2) << setfill('0') << static_cast<int>( i);
  63. }
  64. break;
  65. }
  66. }
  67. delete[] memBlock;
  68. // log << "# # CHECKSUM for filepath '" << filepath << "' " << hex_result.str() << endl;
  69. }else {
  70. log << "could not alloc memory" << endl;
  71. }
  72. file.close();
  73. } else {
  74. log << "file '"<< filepath << "' could not be opened" << endl;
  75. }
  76. return hex_result.str();
  77. }
  78. oxum_t Checksum::oxum_of_file(const string& filepath) {
  79. ifstream file (filepath, ios::ate);
  80. oxum_t oxum{};
  81. //log << "processing file '" << filepath << "'" << endl;
  82. if (file.is_open() ) {
  83. ifstream::pos_type fileSize;
  84. fileSize = file.tellg();
  85. oxum.octetcount = fileSize;
  86. oxum.streamcount = 1;
  87. file.close();
  88. } else {
  89. log << "file '"<< filepath << "' could not be opened" << endl;
  90. }
  91. return oxum;
  92. }
  93. oxum_t Checksum::oxum_of_filelist( list<string> files) {
  94. oxum_t oxum{};
  95. oxum.octetcount=0;
  96. oxum.streamcount=0;
  97. list<string>::iterator i;
  98. for (i=files.begin(); i!= files.end(); ++i) {
  99. oxum_t tmp = this->oxum_of_file( *i );
  100. oxum.octetcount+= tmp.octetcount;
  101. oxum.streamcount+= tmp.streamcount;
  102. }
  103. return oxum;
  104. }
  105. void Checksum::get_logstream( stringstream & log ) {
  106. log << this->log.rdbuf();
  107. }
  108. void Checksum::reset_logstream() {
  109. this->log.str(std::string());
  110. }
  111. // vim: set tabstop=4 softtabstop=0 expandtab shiftwidth=4 smarttab