Advertisement
Guest User

Untitled

a guest
Apr 26th, 2017
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.91 KB | None | 0 0
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #include <io.h>
  3. #include <fcntl.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <math.h>
  8.  
  9. #define MAXVAL 256
  10.  
  11. typedef struct list {
  12. long int data;
  13. int symbol;
  14. struct list *next;
  15. struct list *left;
  16. struct list *right;
  17. } list;
  18.  
  19. long separate(long int a, long int *b) {
  20. *b = a % MAXVAL;
  21. return (a / MAXVAL);
  22. }
  23.  
  24. void push(list **head, long int data, int symbol) {
  25. list *tmp = (list *)malloc(sizeof(list));
  26. tmp->data = data;
  27. tmp->symbol = symbol;
  28. tmp->right = NULL;
  29. tmp->left = NULL;
  30. tmp->next = (*head);
  31. (*head) = tmp;
  32.  
  33. }
  34.  
  35.  
  36. void create_list(list **head, long int *array) {
  37. int i;
  38. for (i = 0; i < MAXVAL; i++) {
  39. if (array[i] != 0)
  40. push(head, array[i], i);
  41. }
  42. }
  43.  
  44. void create_table(unsigned char *array, long int *table, long int size) {
  45. for (long int i = 0; i < size; i++) {
  46. table[(int)array[i]]++;
  47. }
  48. }
  49.  
  50. list *getNth(list *head, int n) {
  51. int counter = 0;
  52. while (counter < n && head) {
  53. head = head->next;
  54. counter++;
  55. }
  56. return head;
  57. }
  58.  
  59. void deleteNth(list **head, int n) {
  60. if (n != 0) {
  61. list *prev = getNth(*head, n - 1);
  62. list *elm = prev->next;
  63. prev->next = elm->next;
  64. //free(elm);
  65. }
  66. else {
  67. (*head) = (*head)->next;
  68. }
  69. }
  70.  
  71. list *find_min(list *head, long int *count, int *position) {
  72. list *tmp = malloc(sizeof(list));
  73. if (tmp == NULL) {
  74. exit(1);
  75. }
  76. int i = 0;
  77. tmp = head;
  78. long int min = head->data;
  79. *position = 0;
  80. head = head->next;
  81. while (head != NULL) {
  82. i++;
  83. if (head->data < min) {
  84. min = head->data;
  85. tmp = head;
  86. (*position) = i;
  87. }
  88. head = head->next;
  89. }
  90. *count = min;
  91. return tmp;
  92. }
  93.  
  94. char code[9] = { "1" };
  95. int count_stack = 1;
  96.  
  97. void preOrderTravers(list *root, long int *array) {
  98. if (root->left != NULL) {
  99. strcpy(&code[count_stack++], "0");
  100. preOrderTravers(root->left, array);
  101. }
  102. if (root->right != NULL) {
  103. strcpy(&code[count_stack++], "1");
  104. preOrderTravers(root->right, array);
  105. }
  106. if (root->symbol >= 0) {
  107. array[root->symbol] = atoi(code);
  108. }
  109. count_stack = (count_stack == 0) ? 1 : count_stack;
  110. strcpy(&code[--count_stack], "\0");
  111. }
  112.  
  113. void create_tree(list **head) {
  114. long int q, e;
  115. int position;
  116. while ((*head)->next != NULL) {
  117. list *tmp = malloc(sizeof(list));
  118. q = 0;
  119. e = 0;
  120.  
  121. list *first = find_min(*head, &q, &position);
  122. deleteNth(head, position);
  123. first->next = NULL;
  124.  
  125. list *second = find_min(*head, &e, &position);
  126. deleteNth(head, position);
  127. second->next = NULL;
  128.  
  129. tmp->data = q + e;
  130. tmp->left = first;
  131. tmp->symbol = -1;
  132. tmp->right = second;
  133. tmp->next = (*head);
  134. (*head) = tmp;
  135. }
  136. }
  137.  
  138. int read_input(FILE *INPUT, long int *array) {
  139. unsigned char buffer[MAXVAL];
  140. long int b;
  141. int i = 0;
  142. fseek(INPUT, 0, SEEK_END);
  143. long int size = ftell(INPUT) - 3;
  144. if (size == 0)
  145. return 1;
  146. fseek(INPUT, 3, SEEK_SET);
  147. long int count = separate(size, &b);
  148. if (count == 0) {
  149. fread(buffer, sizeof(unsigned char), (size_t)b, INPUT);
  150. create_table(buffer, array, b);
  151. }
  152. else {
  153. for (i = 0; i < count; i++) {
  154. fread(buffer, sizeof(unsigned char), MAXVAL, INPUT);
  155. create_table(buffer, array, MAXVAL);
  156. }
  157. fread(buffer, sizeof(unsigned char), (size_t)b, INPUT);
  158. create_table(buffer, array, b);
  159. }
  160. fseek(INPUT, 3, SEEK_SET);
  161. return 0;
  162. }
  163.  
  164. int to_dec(unsigned char *array) {
  165. int a = 0;
  166. for (int i = 0; i < 8; i++) {
  167. a = a + (array[i] - '0') *(int)pow(2, 8 - i - 1);
  168. array[i] = array[8 + i];
  169. }
  170. return a;
  171. }
  172.  
  173. void together(unsigned char *a, unsigned char *b, size_t size_a) {
  174. int j = 0;
  175. size_t size_b = strlen((const char *)b);
  176. for (size_t i = size_a; i < (size_a + size_b); i++) {
  177. a[i] = b[j++];
  178. }
  179. }
  180.  
  181. int encryption(FILE *INPUT, FILE *OUTPUT, long int *array, unsigned char *CodeOfSymbol, size_t *size_source) {
  182.  
  183. unsigned char tmp[17];
  184.  
  185. unsigned char buffer[1];
  186. fread(buffer, sizeof(unsigned char), 1, INPUT);
  187. _itoa(array[(int)buffer[0]], tmp, 10);
  188. size_t size = strlen((const char *)tmp);
  189. for (size_t j = 0; j < size; j++) {
  190. tmp[j] = tmp[j + 1];
  191. }
  192. together(CodeOfSymbol, tmp, *size_source);
  193. *size_source = (size_t)(*size_source + size - 1);
  194. while (*size_source >= 8) {
  195. buffer[0] = (unsigned char)to_dec(CodeOfSymbol);
  196. *size_source = *size_source - 8;
  197. fwrite(buffer, sizeof(unsigned char), 1, OUTPUT);
  198. }
  199. return 0;
  200. }
  201.  
  202. int create_out(FILE *INPUT, FILE *OUTPUT, long int *array) {
  203. long int b = 0, i = 0;
  204. unsigned char buffer[2];
  205. unsigned char CodeOfSymbol[17];
  206. size_t size_source = 0;
  207. fseek(INPUT, 0, SEEK_END);
  208. long int size = ftell(INPUT) - 3;
  209. fseek(INPUT, 3, SEEK_SET);
  210. long int count = separate(size, &b);
  211. if (count != 0) {
  212. for (int j = 0; j < count; j++) {
  213. for (i = 0; i < MAXVAL; i++) {
  214. encryption(INPUT, OUTPUT, array, CodeOfSymbol, &size_source);
  215. }
  216. }
  217. }
  218. for (int l = 0; l < b; l++) {
  219. encryption(INPUT, OUTPUT, array, CodeOfSymbol, &size_source);
  220. }
  221. if (size_source > 0) {
  222. for (i = size_source; i < 8; i++) {
  223. CodeOfSymbol[i] = '0';
  224. }
  225. buffer[0] = (unsigned char)to_dec(CodeOfSymbol);
  226. strcpy((char *)&buffer[1], "\0");
  227. fwrite(buffer, sizeof(unsigned char), 1, OUTPUT);
  228. }
  229. fseek(OUTPUT, 0, SEEK_SET);
  230. fwrite(&size, sizeof(long int), 1, OUTPUT);
  231. return 0;
  232. }
  233.  
  234. //////////////////////////////////////////////////////////////////////////////////
  235. //кодировка дерева
  236. char description[100];
  237. int count_des = 0;
  238.  
  239. void push_element(void) {
  240. strcpy(&description[count_des++], "1");
  241. }
  242.  
  243. void push_symbol(int a) {
  244. char array[8];
  245. int i = 0;
  246. int j = 0;
  247. while (a > 0) {
  248. array[i++] = (char)(a % 2 + '0');
  249. a = a / 2;
  250. }
  251. for (j = 0; j < 8 - i; j++) {
  252. description[count_des++] = '0';
  253. }
  254. i--;
  255. for (j = 0; j < i + 1; j++) {
  256. description[count_des++] = array[i - j];
  257. }
  258. }
  259.  
  260. void shift(FILE *OUTPUT) {
  261. int i;
  262. unsigned char buffer[8];
  263. unsigned char symbol[1];
  264. while (count_des >= 8) {
  265. strncpy((char *)buffer, description, 8);
  266. for (i = 0; i < count_des - 8; i++) {
  267. description[i] = description[i + 8];
  268. }
  269. count_des = count_des - 8;
  270. symbol[0] = (unsigned char)to_dec(buffer);
  271. fwrite(symbol, sizeof(unsigned char), 1, OUTPUT);
  272. }
  273. }
  274.  
  275. void create_descript(FILE *OUTPUT, list *root) {
  276. if (root->left != NULL) {
  277. push_element();
  278. create_descript(OUTPUT, root->left);
  279. }
  280. if (root->right != NULL) {
  281. push_element();
  282. create_descript(OUTPUT, root->right);
  283. }
  284. if (root->symbol >= 0) {
  285. strcpy(&description[count_des++], "0");
  286. push_symbol(root->symbol);
  287. if (count_des >= 8) {
  288. shift(OUTPUT);
  289. }
  290. }
  291. }
  292.  
  293. void tail(FILE *OUTPUT) {
  294. unsigned char buffer[8];
  295. unsigned char symbol[1];
  296. if (count_des != 0) {
  297. for (int i = count_des; i < 8; i++) {
  298. description[i] = '0';
  299. }
  300. strncpy((char *)buffer, description, 8);
  301. symbol[0] = (unsigned char)to_dec(buffer);
  302. fwrite(symbol, sizeof(unsigned char), 1, OUTPUT);
  303. }
  304. }
  305.  
  306.  
  307. //////////////////////////////////////////////////////////////////////////////////
  308. //раскодировка файла
  309. unsigned char buffer = 0;
  310. size_t count = 0;
  311.  
  312. int readBit(FILE *in) {
  313. int res;
  314. size_t readed;
  315. if (count == 0) {
  316. readed = fread(&buffer, sizeof(unsigned char), 1, in);
  317. count = readed * 8;
  318. }
  319. res = buffer & 0x80; // 0x80 == _1_0000000
  320. buffer = buffer << 1;
  321. count--;
  322. return res;
  323. }
  324.  
  325. int readByte(FILE *in) {
  326. int i, res = 0;
  327. for (i = 0; i < 8; i++) {
  328. res = res << 1;
  329. if (readBit(in)) {
  330. res |= 1;
  331. }
  332. }
  333. return res;
  334. }
  335.  
  336. list *readHuffmansTree(FILE *file) {
  337. list *node = malloc(sizeof(list));
  338.  
  339. if (readBit(file) == 0) {
  340. node->symbol = readByte(file);
  341. node->data = 0;
  342. node->left = NULL;
  343. node->right = NULL;
  344. }
  345. else {
  346. node->symbol = -1;
  347. node->data = 0;
  348. node->left = readHuffmansTree(file);
  349. readBit(file);
  350. node->right = readHuffmansTree(file);
  351. }
  352. return node;
  353. }
  354.  
  355.  
  356. void readHeader(FILE *file, list **ppTree, long int *length, long int *alphavite) {
  357. fread(length, sizeof(long int), 1, file);
  358. *ppTree = readHuffmansTree(file);
  359. preOrderTravers(*ppTree, alphavite);
  360. }
  361.  
  362. int decodeByte(FILE *in, list *tree) {
  363. if (tree->symbol != -1) {
  364. return tree->symbol;
  365. }
  366. else if (readBit(in)) {
  367. return decodeByte(in, tree->right);
  368. }
  369. else {
  370. return decodeByte(in, tree->left);
  371. }
  372. }
  373.  
  374. void decode(FILE *infile, FILE *outfile, long int *alphavite) {
  375. int ch;
  376. long int i, length = 0;
  377. list *pTree;
  378.  
  379. readHeader(infile, &pTree, &length, alphavite);
  380. count = 0;
  381. for (i = 0; i<length; i++) {
  382. ch = decodeByte(infile, pTree);
  383. fputc(ch, outfile);
  384. }
  385. }
  386.  
  387.  
  388. int main(void) {
  389. list *head = malloc(sizeof(list));
  390. char buffer[4];
  391. if (head == NULL) {
  392. return 1;
  393. }
  394. head = NULL;
  395. FILE *INPUT;
  396. FILE *OUTPUT;
  397. long int alphavite[MAXVAL] = { 0 };
  398. INPUT = fopen("in.txt", "rb");
  399. if (!INPUT)
  400. return 2;
  401. _setmode(_fileno(INPUT), _O_BINARY);
  402. fgets(buffer, 4, INPUT);
  403. if (buffer[0] == 'c') {
  404. if (read_input(INPUT, alphavite)) { //подсчитываем количество вхождений символов в файле
  405. return 0;
  406. }
  407. create_list(&head, alphavite); //создаём список встречающихся символов
  408. create_tree(&head); //создаём бинарное дерево
  409. preOrderTravers(head, alphavite); //обходим дерево
  410. OUTPUT = fopen("out.txt", "wb");
  411. _setmode(_fileno(OUTPUT), _O_BINARY);
  412. if (!OUTPUT) {
  413. return 4;
  414. }
  415. fseek(OUTPUT, sizeof(long int), SEEK_SET);
  416. create_descript(OUTPUT, head); //записываем дерево
  417. tail(OUTPUT); //
  418. create_out(INPUT, OUTPUT, alphavite); //создание шифрованного файла
  419. fclose(OUTPUT);
  420. fclose(INPUT);
  421. }
  422. else {
  423. if (buffer[0] == 'd') {
  424. OUTPUT = fopen("out.txt", "wb");
  425. _setmode(_fileno(OUTPUT), _O_BINARY);
  426. if (!OUTPUT)
  427. return 6;
  428. decode(INPUT, OUTPUT, alphavite);
  429. fclose(OUTPUT);
  430. fclose(INPUT);
  431. }
  432. }
  433. free(head);
  434. return 0;
  435. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement