streamhash/main.c

62 lines
1.6 KiB
C
Raw Permalink Normal View History

2021-08-08 15:01:42 +00:00
#include <stdio.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#define CHUNK_SIZE 8 * 1024
int main(int argc, char *argv[]) {
if (argc == 0) {
fprintf(stderr, "Usage: streamhash <algorithm>\n");
return 1;
}
if (argc != 2) {
fprintf(stderr, "Usage: %s <algorithm>\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;
}