main.c (2062B)
1 #include <stdio.h> 2 #include <string.h> 3 #include <stdlib.h> 4 5 static inline int char_to_hex(unsigned char *val, char c) 6 { 7 if (c >= '0' && c <= '9') { 8 *val = c - '0'; 9 return 1; 10 } 11 if (c >= 'a' && c <= 'f') { 12 *val = c - 'a' + 10; 13 return 1; 14 } 15 if (c >= 'A' && c <= 'F') { 16 *val = c - 'A' + 10; 17 return 1; 18 } 19 return 0; 20 } 21 22 static inline int hex_decode(const char *str, size_t slen, void *buf, size_t bufsize) 23 { 24 unsigned char v1, v2; 25 unsigned char *p = buf; 26 27 while (slen > 1) { 28 if (!char_to_hex(&v1, str[0]) || !char_to_hex(&v2, str[1])) 29 return 0; 30 if (!bufsize) 31 return 0; 32 *(p++) = (v1 << 4) | v2; 33 str += 2; 34 slen -= 2; 35 bufsize--; 36 } 37 return slen == 0 && bufsize == 0; 38 } 39 40 static inline size_t hex_str_size(size_t bytes) 41 { 42 return 2 * bytes + 1; 43 } 44 45 static inline char hexchar(unsigned int val) 46 { 47 if (val < 10) 48 return '0' + val; 49 if (val < 16) 50 return 'a' + val - 10; 51 abort(); 52 } 53 54 static inline int hex_encode(const void *buf, size_t bufsize, char *dest, size_t destsize) 55 { 56 size_t i; 57 58 if (destsize < hex_str_size(bufsize)) { 59 fprintf(stderr, "hexencode: destsize(%zu) < hex_str_size(%zu)\n", destsize, hex_str_size(bufsize)); 60 return 0; 61 } 62 63 for (i = 0; i < bufsize; i++) { 64 unsigned int c = ((const unsigned char *)buf)[i]; 65 *(dest++) = hexchar(c >> 4); 66 *(dest++) = hexchar(c & 0xF); 67 } 68 *dest = '\0'; 69 70 return 1; 71 } 72 73 74 static inline int zero_bits(unsigned char b) 75 { 76 int n = 0; 77 78 if (b == 0) 79 return 8; 80 81 while (b >>= 1) 82 n++; 83 84 return 7-n; 85 } 86 87 /* find the number of leading zero bits in a hash */ 88 static int count_leading_zero_bits(unsigned char *hash, int len) 89 { 90 int bits, total, i; 91 92 for (i = 0, total = 0; i < len; i++) { 93 bits = zero_bits(hash[i]); 94 total += bits; 95 if (bits != 8) 96 break; 97 } 98 return total; 99 } 100 101 int main(int argc, const char *argv[]) 102 { 103 unsigned char buf[4096]; 104 const char *hex; 105 int bits, len; 106 107 if (argc < 1) 108 return 1; 109 110 hex = argv[1]; 111 len = strlen(hex); 112 113 if (!hex_decode(hex, len, buf, len/2)) 114 return 2; 115 116 bits = count_leading_zero_bits(buf, len / 2); 117 printf("%d\n", bits); 118 return 0; 119 }