I was playing around with file I/O the C++ way and decided to create a file hashing program using ifstream and Botan crypto library. The program reads an entire file specified as the command line argument and takes the SHA1 hash of the content. It’s amazing what you can accomplish with well designed frameworks in very little code. Here’s the program (file_hash.cpp):
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 |
#include <iostream> #include <fstream> #include <ios> #include <vector> #include <botan-2/botan/hash.h> #include <botan-2/botan/hex.h> using namespace std; const int READ_SIZE = 1024 * 1024; int main(int argc, char** argv) { if(argc != 2) { cerr << "USAGE: " << argv[0] << " <file name>" << endl; return -1; } try { using Buffer = vector<char>; Buffer buffer(READ_SIZE); auto sha1 = Botan::HashFunction::create_or_throw("SHA-1"); ifstream ifs; ifs.exceptions(ios::failbit | ios::badbit); ifs.open(argv[1]); ifs.seekg(0, ios_base::end); size_t bytes_left = ifs.tellg(); ifs.seekg(ios_base::beg); while(bytes_left) { size_t bytes_to_read = bytes_left > READ_SIZE ? READ_SIZE : bytes_left; buffer.resize(bytes_to_read); ifs.read(buffer.data(), buffer.size()); sha1->update((uint8_t*)buffer.data(), buffer.size()); bytes_left -= bytes_to_read; } ifs.close(); cout << Botan::hex_encode(sha1->final()) << " " << argv[1] << endl; } catch(exception& e) { cerr << e.what() << endl; } } |
Why not use a stringstream?