Advertisement
wizard2012

hdist utility

Jan 11th, 2025 (edited)
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.19 KB | Source Code | 0 0
  1. // SPDX-License-Identifier: BSD-3-Clause
  2. // See file LICENSE.txt for more information.
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. #define VERSION_STR "0.0.1"
  9.  
  10. #ifdef _MSC_VER
  11. #define popcnt(x) __popcnt(x)
  12. #else
  13. #define popcnt(x) __builtin_popcount(x)
  14. #endif
  15.  
  16. static int hex_to_bin(char c)
  17. {
  18.   if (c >= '0' && c <= '9') return c - '0';
  19.   if (c >= 'A' && c <= 'F') return c - 'A' + 10;
  20.   if (c >= 'a' && c <= 'f') return c - 'a' + 10;
  21.   return -1;
  22. }
  23.  
  24. int main(int argc, char** argv)
  25. {
  26.   if (argc == 2) {
  27.     if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) {
  28.       printf("%s\n", VERSION_STR);
  29.       return EXIT_SUCCESS;
  30.     }
  31.  
  32.     if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
  33.       printf("usage: %s [OPTION] [HEX1 HEX2]\n", argv[0]);
  34.       puts(
  35.           "\n"
  36.           "Compute Hamming distance between two hexadecimal numbers of the arbitrary precision.\n"
  37.           "\n"
  38.           "HEX1 and HEX2 must be of the same length\n"
  39.           "\n"
  40.           "Options:\n"
  41.           "  -h, --help       Print this help message and exit\n"
  42.           "  -v, --version    Print version and exit\n"
  43.       );
  44.       return EXIT_SUCCESS;
  45.     }
  46.   }
  47.  
  48.   if (argc != 3) {
  49.     fprintf(stderr, "error: %s arguments\nTry '%s --help' for more information\n",
  50.       argc < 3 ? "missing required" : "too many",
  51.       argv[0]);
  52.     exit(EXIT_FAILURE);
  53.   }
  54.  
  55.   const size_t len = strlen(argv[1]);
  56.   if (strlen(argv[2]) != len) {
  57.     fputs("error: lengths of arguments are different.", stderr);
  58.     exit(EXIT_FAILURE);
  59.   }
  60.  
  61.   unsigned long long d = 0;
  62.  
  63.   const char * const p1_end = argv[1] + len;
  64.   for (const char *p1 = argv[1], *p2 = argv[2]; p1 != p1_end; ++p1, ++p2) {
  65.     const int bin1 = hex_to_bin(*p1);
  66.     const int bin2 = hex_to_bin(*p2);  
  67.     if (bin1 >= 0 && bin2 >=0) {
  68.       d += popcnt(bin1 ^ bin2);  
  69.     } else {
  70.       const int arg_no = bin1 < 0 ? 1 : 2;
  71.       fprintf(stderr, "error: non-hex character at position %td in the argument %d\n",
  72.         (arg_no == 1 ? p1 - argv[1] : p2 - argv[2]) + 1,
  73.         arg_no);
  74.       exit(EXIT_FAILURE);
  75.     }
  76.   }
  77.  
  78.   printf("%llu\n", d);
  79.   return EXIT_SUCCESS;
  80. }
  81.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement