1#include <assert.h> 2#include <fcntl.h> 3#include <stdio.h> 4#include <sys/mman.h> 5#include <sys/stat.h> 6#include <sys/time.h> 7#include <unistd.h> 8 9#include <openssl/sha.h> 10 11inline double now() 12{ 13 struct timeval tv = { 0, 0 }; 14 gettimeofday(&tv, nullptr); 15 return tv.tv_sec + tv.tv_usec / 1000000.0; 16} 17 18int main(int argc, char* argv[]) 19{ 20 int64_t total = 0; 21 double start = now(); 22 SHA_CTX ctx_; 23 SHA1_Init(&ctx_); 24 for (int i = 1; i < argc; ++i) 25 { 26 int fd = open(argv[i], O_RDONLY); 27 struct stat st; 28 fstat(fd, &st); 29 size_t len = st.st_size; 30 total += len; 31 if (len < 1024*1024*1024) 32 { 33 void* mapped = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); 34 assert(mapped != MAP_FAILED); 35 SHA1_Update(&ctx_, mapped, len); 36 munmap(mapped, len); 37 } 38 else 39 { 40 char buf[128*1024]; 41 ssize_t nr; 42 while ( (nr = read(fd, buf, sizeof buf)) > 0) 43 { 44 SHA1_Update(&ctx_, buf, nr); 45 } 46 } 47 ::close(fd); 48 } 49 unsigned char result[SHA_DIGEST_LENGTH]; 50 SHA1_Final(result, &ctx_); 51 for (int i = 0; i < SHA_DIGEST_LENGTH; ++i) 52 { 53 printf("%02x", result[i]); 54 } 55 printf("\n"); 56 double sec = now() - start; 57 printf("%ld bytes %.3f sec %.2f MiB/s\n", total, sec, total / sec / 1024 / 1024); 58} 59 60