Kirokyri

C7

Nov 20th, 2020 (edited)
561
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <string.h>
  5.  
  6. #include <unistd.h>
  7. #include <crypt.h>
  8. #include <time.h>
  9.  
  10. #include <pthread.h>
  11. #include <semaphore.h>
  12.  
  13. #define PROC_NUM sysconf(_SC_NPROCESSORS_ONLN);                             //
  14.  
  15. typedef enum
  16. {
  17.     BM_ITER,
  18.     BM_REC,
  19. } brute_mode_t;
  20.  
  21. typedef enum                                                                //
  22. {
  23.     TM_SINGLE,
  24.     TM_MULTI,
  25. } thread_mode_t;
  26.  
  27. typedef struct config_t {
  28.     brute_mode_t brute_mode;
  29.     thread_mode_t thread_mode;                                              //
  30.     int length;
  31.     char * alphabet;
  32.     char * hash;
  33. } config_t;
  34.  
  35. typedef struct task_t {
  36.     char password[8];
  37. } task_t;
  38.  
  39. typedef struct queue_t {
  40.     task_t queue[8];
  41.     int head, tail;
  42.     pthread_mutex_t head_mutex, tail_mutex;
  43.     sem_t empty, full;
  44. } queue_t;
  45.  
  46. typedef bool (*password_handler_t) (config_t * config, char * password);
  47.  
  48. void queue_init (queue_t * queue)
  49. {
  50.     queue->head = 0;
  51.     queue->tail = 0;
  52.     pthread_mutex_init (&queue->head_mutex, NULL);
  53.     pthread_mutex_init (&queue->tail_mutex, NULL);
  54.     sem_init (&queue->empty, 0, sizeof (queue->queue) / sizeof (queue->queue[0]));
  55.     sem_init (&queue->full, 0, 0);
  56. }
  57.  
  58. void queue_push (queue_t * queue, task_t * task)
  59. {
  60.     //7
  61.     sem_wait (&queue->empty);
  62.     pthread_mutex_lock (&queue->tail_mutex);
  63.     queue->queue[queue->tail] = *task;
  64.     if (++queue->tail == sizeof (queue->queue) / sizeof (queue->queue[0]))
  65.         queue->tail = 0;
  66.     pthread_mutex_unlock (&queue->tail_mutex);
  67.     sem_post (&queue->full);
  68.  
  69. }
  70.  
  71. void queue_pop (queue_t * queue, task_t * task)
  72. {
  73.     //7
  74.     sem_wait(&queue->full);
  75.     pthread_mutex_lock (&queue->head_mutex);
  76.     if (++queue->head == sizeof (queue->queue) / sizeof (queue->queue[0]))
  77.         queue->head = 0;
  78.     pthread_mutex_unlock (&queue->head_mutex);
  79.     sem_post (&queue->empty);
  80. }
  81.  
  82. bool rec(config_t* config, char* password, int pos, password_handler_t password_handler)
  83. {
  84.     int i;
  85.     if (pos >= config->length)
  86.     {
  87.         if (password_handler (config, password))
  88.         {
  89.             return (true);
  90.         }
  91.     }
  92.     else
  93.     {
  94.         for (i = 0; config->alphabet[i]; ++i)
  95.         {
  96.             password[pos] = config->alphabet[i];
  97.             if (rec (config, password, pos + 1, password_handler))
  98.                 return (true);
  99.         }
  100.     }
  101.     return (false);
  102. }
  103.  
  104. void rec_wrapper(config_t* config, char* password, password_handler_t password_handler)
  105. {
  106.     rec (config, password, 0, password_handler);
  107. }
  108.  
  109. void iter(config_t* config, char* password, password_handler_t password_handler)
  110. {
  111.     int alph_length_1 = strlen(config->alphabet) - 1;
  112.     int idx[config->length];
  113.     int i;
  114.  
  115.     for (i = 0; i < config->length; i++)
  116.     {
  117.         idx[i] = 0;
  118.         password[i] = config->alphabet[0];
  119.     }
  120.  
  121.     for (;;)
  122.     {
  123.          if (password_handler (config, password))
  124.             break;
  125.         for (i = config->length - 1; (i >= 0) && (idx[i] == alph_length_1); i--)
  126.         {
  127.             idx[i] = 0;
  128.             password[i] = config->alphabet[0];
  129.         }
  130.  
  131.         if (i < 0)
  132.             break;
  133.  
  134.         password[i] = config->alphabet[++idx[i]];
  135.     }
  136. }
  137.  
  138. void parse_params(config_t* config, int argc, char* argv[])
  139. {
  140.     for (;;)
  141.     {
  142.         int opt = getopt(argc, argv, "a:l:h:irsm");                         //
  143.         if (opt == -1)
  144.             break;
  145.         switch (opt)
  146.         {
  147.         case 's':
  148.             config->thread_mode = TM_SINGLE;                                //
  149.             break;
  150.  
  151.         case 'm':
  152.             config->thread_mode = TM_MULTI;                                 //
  153.             break;
  154.  
  155.         case 'i':
  156.             config->brute_mode = BM_ITER;
  157.             break;
  158.  
  159.         case 'r':
  160.             config->brute_mode = BM_REC;
  161.             break;
  162.  
  163.         case 'a':
  164.             config->alphabet = optarg;
  165.             break;
  166.  
  167.         case 'h':
  168.             config->hash = optarg;
  169.             break;
  170.  
  171.         case 'l':
  172.             config->length = atoi(optarg);
  173.             break;
  174.  
  175.         default:
  176.             break;
  177.         }
  178.     }
  179. }
  180.  
  181. bool print_password (config_t * config, char * password)
  182. {
  183.     printf ("%s\n", password);
  184.     return (false);
  185. }
  186.  
  187. bool check_password (config_t * config, char * password)
  188. {
  189.     char * hash = crypt (password, config->hash);
  190.     int cmp = strcmp (hash, config->hash);
  191.     return (0 == cmp);
  192. }
  193.  
  194. int main(int argc, char* argv[])
  195. {
  196.     config_t config =
  197.     {
  198.         .thread_mode = TM_SINGLE,                                           //
  199.         .brute_mode = BM_ITER,
  200.         .alphabet = "01",
  201.         .length = 6,
  202.         .hash = strdup (crypt ("111101", "11")),
  203.     };
  204.    
  205.     queue_t queue;
  206.     queue_init (&queue);
  207.  
  208.     parse_params(&config, argc, argv);
  209.  
  210.     char password[config.length + 1];
  211.     password[config.length] = 0;
  212.  
  213.     if (config.thread_mode == TM_MULTI)                                     //
  214.     {
  215.         pthread_t id[PROC_NUM];
  216.         int i;
  217.         for (i = 0; i < proc_num; i++)
  218.             pthread_create (&id[i], NULL, /* fun */, NULL);
  219.     }
  220.    
  221.     switch (config.brute_mode)
  222.     {
  223.         case BM_ITER:
  224.             iter (&config, password, check_password);
  225.             break;
  226.         case BM_REC:
  227.             rec_wrapper(&config, password, check_password);
  228.             break;
  229.     }
  230.     printf ("%s\n", password);
  231.     return (EXIT_SUCCESS);
  232. }
  233.  
RAW Paste Data