hash.c (3271B)
1 /* 2 * Unified Hash API Implementation 3 */ 4 5 #include "hash.h" 6 #include <stdio.h> 7 #include <stdlib.h> 8 #include <string.h> 9 10 // One-shot hash computation 11 HashResult hash_compute(HashAlgorithm algo, const uint8_t *data, size_t len) { 12 HashResult result; 13 result.algorithm = algo; 14 result.digest_len = hash_digest_length(algo); 15 result.digest = malloc(result.digest_len); 16 17 if (!result.digest) { 18 result.digest_len = 0; 19 return result; 20 } 21 22 switch (algo) { 23 case HASH_SHA256: 24 sha256(data, len, result.digest); 25 break; 26 27 case HASH_SHA512: 28 sha512(data, len, result.digest); 29 break; 30 31 case HASH_SHA1: 32 sha1(data, len, result.digest); 33 break; 34 35 case HASH_MD5: 36 md5(data, len, result.digest); 37 break; 38 39 case HASH_CRC32: { 40 uint32_t crc = crc32(data, len); 41 result.digest[0] = (crc >> 24) & 0xFF; 42 result.digest[1] = (crc >> 16) & 0xFF; 43 result.digest[2] = (crc >> 8) & 0xFF; 44 result.digest[3] = crc & 0xFF; 45 break; 46 } 47 48 default: 49 free(result.digest); 50 result.digest = NULL; 51 result.digest_len = 0; 52 break; 53 } 54 55 return result; 56 } 57 58 // Free hash result 59 void hash_free(HashResult *result) { 60 if (result && result->digest) { 61 free(result->digest); 62 result->digest = NULL; 63 result->digest_len = 0; 64 } 65 } 66 67 // Print hash in hex format 68 void hash_print(const char *label, const HashResult *result) { 69 if (!result || !result->digest) { 70 printf("%s: (null)\n", label); 71 return; 72 } 73 74 printf("%s (%s): ", label, hash_algorithm_name(result->algorithm)); 75 76 if (result->algorithm == HASH_CRC32) { 77 // Print CRC32 as a single hex number 78 uint32_t crc = ((uint32_t)result->digest[0] << 24) | 79 ((uint32_t)result->digest[1] << 16) | 80 ((uint32_t)result->digest[2] << 8) | 81 ((uint32_t)result->digest[3]); 82 printf("0x%08x\n", crc); 83 } else { 84 // Print hash digests as continuous hex 85 for (size_t i = 0; i < result->digest_len; i++) { 86 printf("%02x", result->digest[i]); 87 } 88 printf("\n"); 89 } 90 } 91 92 // Convert hash to hex string 93 char* hash_to_hex(const HashResult *result) { 94 if (!result || !result->digest) { 95 return NULL; 96 } 97 98 size_t hex_len; 99 if (result->algorithm == HASH_CRC32) { 100 hex_len = 11; // "0x" + 8 hex digits + null terminator 101 } else { 102 hex_len = result->digest_len * 2 + 1; // 2 hex chars per byte + null 103 } 104 105 char *hex = malloc(hex_len); 106 if (!hex) { 107 return NULL; 108 } 109 110 if (result->algorithm == HASH_CRC32) { 111 uint32_t crc = ((uint32_t)result->digest[0] << 24) | 112 ((uint32_t)result->digest[1] << 16) | 113 ((uint32_t)result->digest[2] << 8) | 114 ((uint32_t)result->digest[3]); 115 snprintf(hex, hex_len, "0x%08x", crc); 116 } else { 117 for (size_t i = 0; i < result->digest_len; i++) { 118 snprintf(hex + i * 2, 3, "%02x", result->digest[i]); 119 } 120 } 121 122 return hex; 123 }