Воскресенье, 13.09.2026, 03:47
СГУ.clan - в помощь студентам!
Главная | Регистрация |Вход Приветствую Вас Школьник | RSS
Меню сайта
ПОИСК ДЛЯ ПРОГРАММИСТОВ
 Google поиск для программистов
Категории каталога
Статьи [22]
Не СГУ [9]
Факультет КНиИТ [340]
Биологический факультет [16]
Географический факультет [31]
Геологический факультет [36]
Институт истории [67]
Механико-математический факультет [190]
Социологический факультет [68]
Фак-т нано и биомедицинских техн... [99]
Факультет нелинейных процессов [36]
Физический факультет [66]
Институт филологии и журналистики [29]
Химический факультет [70]
Экономический факультет [55]
Юридический факультет [31]
Наш опрос
Каких оценок в Вашей зачетке больше?
Всего ответов: 240

Напоминаем, что если необходимый Вам файл был удален с сервера DepositFiles (за исключением просьбы автора), то Вы можете написать в комментарии о необходимости в данном файле. В ближайшее время он будет перезалит (при возможности на сервер сайта).

Главная » Файлы » Статьи [ Добавить материал ]

Реализация producer-consumer на С
[ ] 25.12.2008, 00:17
Собственно, есть у нас есть producer - он вырабатывает новые задачи и добавляет их в очередь (в это примере стек). И есть несколько consumer'ов - он извлекает задачу из очереди и выполняет её. Задача - перебор пароля, и сравнение его хэша с введенным в программу хэшом. Диапазон перебора от 'a' до 'z' по аски.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <crypt.h>
#include <pthread.h>
#include <semaphore.h>

#define MAXXPASS_LEN 50 // макс. длина пароля
#define MAXX_STACK_LEN 10000 // объём стека
#define MAX_THREADS 5 // кол-во консюмеров

struct task_d{
  char *pass,*hash; // это структура задачи. содержит хэш и пароль
};

struct tstack{
  int length; // длина стека (кол-во задач в нём)
  struct task_d *task; // масив этих самых задач
};

struct tstack *stack; // опишем глобально указатель на структуру стека
char hash[50]; // а здесь будет введённый хэш, получаемый при запуске программы
sem_t empts,fulls; // семафорчики, epmts - следит за кол-вом свободных задач в стека, fulls - количество занесенных задач в стека
pthread_mutex_t crit; // для доступа к стеку на чтение / запись

void push(struct tstack *s, struct task_d *tas){ // ну ничего интересного, помещает задачу в стек
  s->task=realloc(s->task,(sizeof(struct task_d))*(1+s->length));
  s->task[s->length].pass=malloc(sizeof(char)*MAXXPASS_LEN);
  s->task[s->length].hash=malloc(sizeof(char)*MAXXPASS_LEN);
  strcpy(s->task[s->length].pass,tas->pass);
  strcpy(s->task[s->length].hash,tas->hash);
  s->length++;
}

void pop(struct tstack *s, struct task_d *tas){ // извлекает задачу из него
  if (s->length){
  s->length--;
  strcpy(tas->pass,s->task[s->length].pass);
  strcpy(tas->hash,s->task[s->length].hash);
  free(s->task[s->length].hash);
  free(s->task[s->length].pass);
  s->task=realloc(s->task,(sizeof(struct task_d))*(s->length));
  return;
  }  
  tas->pass=tas->hash=NULL;
}

char *getnextpas(char *pass,int UP, int DO){ // вырабатывает новую задачу (зависит от предудыщей и от диапазона значение UP - DO [для простоты UP='a' ; DO='z']
  int len,j=0;
  pass[0]= pass[0]+1;
  len=strlen(pass);
  for (;j<len-1;j++){ // какието хитрые действа
  if (pass[j]>DO) {
  pass[j]=UP;
  if (pass[j+1]!=0) {
  pass[j+1] = pass[j+1]+1;
  } else {
  pass[j+1] = UP;
  }
  }
  }
  if (pass[len-1]>DO){
  pass[len]=UP;
  pass[len-1]=UP;
  if (pass[0]>DO){
  pass[0]=UP;
  }
  }
  return pass; // вот и результат
}

int checkpas(struct task_d *task,struct crypt_data *data, char *hash){ // этим методом консюмер решает задачу
  return strcmp(hash,(crypt_r(task->pass,hash,data)));
}

void *consumer(void *argc){ // сам консюмер
  struct task_d *task=malloc(sizeof(struct task_d));
  task->pass=malloc(sizeof(char)*MAXXPASS_LEN);
  task->hash=malloc(sizeof(char)*MAXXPASS_LEN);
  struct crypt_data *data=malloc(sizeof(struct crypt_data));
  data->initialized=0;
  for(;;){
  sem_wait(&fulls); // уменьшеть кол-во задач в стеке
  pthread_mutex_lock(&crit); // крит.секция
  pop(stack,task); // получить задачу из стека
  pthread_mutex_unlock(&crit); // крит.секция
  sem_post(&empts); // увеличени кол-ва извлеченных задач в стек
  if (task->pass!=task->hash)
  if (!checkpas(task,data,hash)) { // решает задачу
  printf("pass=%s\n",task->pass); // при успехе выводи результат и завершает программу
  exit(0);
  }
  }
  return NULL;
}

void *producer(void *argc){
  char *lastpass=malloc(sizeof(char)*MAXXPASS_LEN);
  lastpass[0]='a'-1;
  struct task_d *task=malloc(sizeof(struct task_d));
  task->pass=malloc(sizeof(char)*MAXXPASS_LEN);
  task->hash=malloc(sizeof(char)*MAXXPASS_LEN);
  for(;;){
  sem_wait(&empts); //уменьшает кол-во свободных задач в стеке
  strcpy(task->pass,getnextpas(lastpass,'a','z')); // строим новую задачу
  strcpy(task->hash,hash);
  pthread_mutex_lock(&crit); // крит.секция
  push(stack,task); // добавляем её в стек
  pthread_mutex_unlock(&crit); // крит.секция
  sem_post(&fulls); // увеличееваем кол-во занесенных в стек задач
  }
}

int main (int argc, char **argv){
  stack=malloc(sizeof(struct tstack));
  stack->length=0;
  stack->task=NULL;
  pthread_t threads[MAX_THREADS];
  strcpy(hash,argv[1]);
  sem_init(&fulls,0,0); // у нас изначально занесенных в стек задач 0
  sem_init(&empts,0,MAXX_STACK_LEN); // а количество свободных мест в стеке MAXX_STACK_LEN
  pthread_mutex_init(&crit,NULL);
  int i=0;
  pthread_create(&threads[i],NULL,producer,NULL); // стартуем продюсера
  i++;
  for(;i<MAX_THREADS;i++){
  pthread_create(&threads[i],NULL,consumer,NULL); // и консюмеров
  }
  pthread_join(threads[0],NULL);
  return 0;
}

компилируется так
gcc stack.c -o stack -g -lcrypt -lpthread -D_GNU_SOURCE
а запускать
./stack HASH
где HASH - это хэш. чтото похожее на ZVfdoDq90ky6Y

а ниже программа которая делает этот хэш...
на каждый запуск выдаёт новый хэш (зависит от pid процесса) + может выдавать md5 хэши для crypt

#include <crypt.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <features.h>
int main (int argc, char **argv){
  const char *const seedchars =
  "./0123456789ABCDEFGHIJKLMNOPQRST"
  "UVWXYZabcdefghijklmnopqrstuvwxyz";
  char salt[11];
  char hash[34];
  srand(getpid());
  if (argc<2) {
  printf("Usage: cr <pass> [-md5]\n");
  return 1;}
  if (argc>2){
  //md5
  salt[0]='$';salt[1]='1';salt[2]='$';
  for (int i=0;i<8;i++)
  salt[3+i]=seedchars[(int) (63.0 * (rand() / (RAND_MAX + 1.0)))];
  } else {
  //des
  for (int i=0;i<2;i++)
  salt[i]=seedchars[(int) (63.0 * (rand() / (RAND_MAX + 1.0)))];
  }
  printf("%s\n", strcpy(hash,crypt(argv[1],salt)));
  return 0;
}

она компилируется так
gcc -g -lcrypt -lm -std=c99 -D_POSIX_C_SOURCE cr.c -o cr

тогда в общем виде получаем, что можно запустить так
./stack $(./cr your_pass)
где your_pass - ваш пароль.

Категория: Статьи |
Просмотров: 784 | Загрузок: 0 | Комментарии: 1 | Рейтинг: 5.0/2 |

Данный файл Вам очень помог? Вы можете отблагодарить автора!

Всего комментариев: 1
1 thor  
0
форматирование испортилось angry

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Форма входа

Правильные покупки

Поиск
Друзья сайта


Статистика

Онлайн всего: 1
Гостей: 1
Пользователей: 0
Copyright СГУ.clan © 2026