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