62 lines
1.6 KiB
C
62 lines
1.6 KiB
C
#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;
|
|
}
|