Advertisement
Guest User

Untitled

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