#include #include #include #define CHUNK_SIZE 8 * 1024 int main(int argc, char *argv[]) { if (argc == 0) { fprintf(stderr, "Usage: streamhash \n"); return 1; } if (argc != 2) { fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } const EVP_MD *type = EVP_get_digestbyname(argv[1]); if (!type) { fprintf(stderr, "Invalid algorithm: %s\n", argv[1]); return 1; } EVP_MD_CTX *ctx = EVP_MD_CTX_new(); if (EVP_DigestInit(ctx, type) != 1) { ERR_print_errors_fp(stderr); return 1; } char chunk[CHUNK_SIZE]; char loop = 1; while (loop) { size_t size = fread(chunk, 1, CHUNK_SIZE, stdin); if (size != CHUNK_SIZE) { if (feof(stdin)) loop = 0; else { EVP_MD_CTX_free(ctx); perror("fread"); return 1; } } if (fwrite(chunk, 1, size, stdout) != size) { EVP_MD_CTX_free(ctx); perror("fwrite"); return 1; } if (EVP_DigestUpdate(ctx, chunk, size) != 1) { EVP_MD_CTX_free(ctx); ERR_print_errors_fp(stderr); return 1; } } unsigned char md[EVP_MAX_MD_SIZE]; unsigned int size; if (EVP_DigestFinal(ctx, md, &size) != 1) { ERR_print_errors_fp(stderr); EVP_MD_CTX_free(ctx); return 1; } for (unsigned int i=0; i < size; i++) fprintf(stderr, "%02x", md[i]); fprintf(stderr, "\n"); return 0; }