You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
61 lines
1.6 KiB
61 lines
1.6 KiB
#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; |
|
}
|
|
|