Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Работа для программиста > Фриланс
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.03.2018, 16:17   #1
Татьяна12345678
Новичок
Джуниор
 
Регистрация: 21.03.2018
Сообщений: 0
По умолчанию сжатие данных методом LZ-77 C++

Помогите отредактировать код! Либо написать заново! Кодирование и декодирование введенной строчки
Код:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <fcntl.h>
#include <io.h>

#define DICBITS   12             
#define DICSIZE   (1<<DICBITS)   
#define THRESHOLD 2             
#define STRBITS   6              
#define STRMAX    ((1<<STRBITS)+THRESHOLD) 
#define BUFSIZE   0xff00U        
#define TEXTSIZE  (BUFSIZE-DICSIZE-STRMAX) 
#define YES       1
#define NO        0

long fileleng;
int srcleng = 0;
unsigned char *srcbuf, *srcstart;

void coding(char fnamein[], char fnameout[], char code[], int p = 1)      //кодировка сдвигом
{	
	FILE *in = fopen(fnamein, "rb");
	FILE *out = fopen(fnameout, "wb");
	if (in == NULL || out == NULL) return;
	int len = strlen(code);
	int i = 0;
	int ch;
	while ((ch = getc(in)) != EOF)
	{
		int c = (ch + p * code[i%len]) % 256;
		putc(c, out);
		i++;
	}
	fclose(in);
	fclose(out);
}

unsigned int crc16(char fname[])
{
	FILE *in = fopen(fname, "r");
	if (in == NULL) return 0;
	unsigned int crc = 0xFFFF;
	unsigned char i;
	unsigned char ch;
	while (fscanf(in, "%c", &ch) != EOF)
	{
		crc ^= ch << 8;
		for (i = 0; i < 8; i++)
		{
			if (crc & 0x8000)
				crc = (crc << 1) ^ 0x1021;
			else
				crc = crc << 1;
		}
	}
	fclose(in);
	return crc;
}

int putbits(int data, int nbits, char fileout[])       //функция записи
{
	FILE *out = fopen(fileout, "w");
	static int bitcounter = 0;
	static int outdata = 0;
	int bit, error;
	data <<= (16 - nbits);
	for (; nbits > 0; nbits--)
	{
		if (bitcounter == 8)
		{
			bitcounter = 0;
			error = putc(outdata, out);
			if (error == EOF)
			{
				printf("Error writing to Second file.");
				return -5;
			}
		}
		outdata <<= 1;
		bit = (data & 0x8000) ? 1 : 0;
		outdata += bit;
		bitcounter++;
		data <<= 1;
	}
}

void compress_stud(char *filein, char *fileout)      //функция архивирования
{
	unsigned char  *position, *pointer; //байт в файле , байт в буфере
	int i, dist, offset = 0, last = NO, cnt, maxleng;
	printf("Compressing...");
	FILE *in = fopen(filein, "r");  // Читаем файл в буфер по частям размера TEXTSIZE 
	while ((srcleng = fread(srcstart + offset, 1, TEXTSIZE, in))>0)
	{
		if (srcleng < TEXTSIZE) // Последняя часть текста 
		{
			last = YES;
		}
		position = srcstart;
		pointer = srcbuf;
		srcleng += offset;
		printf("\n\nStep - %d\n", srcleng);
		maxleng = 0;
		if ((last == NO) && (srcleng < STRMAX)) // Если в буфере текста осталось мало символов, сдвигаем словарь и оставшийся текст в начало буфера и дочитываем следующую часть из файла 
		{
			memcpy(srcbuf, pointer, DICSIZE + (int)srcleng);
			offset = (int)srcleng;
			break;
		}
		for (i = DICSIZE - 1; i >= 0; i--) // Ищем самую длинную совпадающую строку в словаре
		{
			for (cnt = 0; cnt < STRMAX; cnt++)
				if (*(position + cnt) != *(pointer + i + cnt))
					break;
			if (cnt <= THRESHOLD)// Если длина меньше порога, отбрасываем  
				continue;
			if (cnt == STRMAX)// Если максимальная строка, дальше не ищем 
			{
				dist = DICSIZE - 1 - i; //позиция
				maxleng = STRMAX;
				break;
			}
			if (cnt > maxleng) // Если очередная строка длиннее уже найденных, сохраняеМ ее длину и позицию
			{
				dist = DICSIZE - 1 - i; // позиция
				maxleng = cnt; //длина
			}
		}
		if ((last == YES) && (maxleng > srcleng)) // Проверяем, чтобы не было выхода за границы файла
		{
			maxleng = (int)srcleng; //обрезаем длину по границу буфера
		}
		if (maxleng > THRESHOLD)//Если строка достаточно длинная, формируем pointer-код
		{
			printf("link!\n");
			putbits(1, 1, fileout); //помечаем как ссылку
			putbits(dist, DICBITS, fileout); //записываем позицию
			putbits(maxleng - THRESHOLD - 1, STRBITS, fileout); //записываем длину
			position += maxleng;
			srcleng -= maxleng;
			pointer += maxleng;
		}
		else // Иначе - chr-код
		{
			printf("Char!\n");
			putbits(0, 1, fileout);  //помечаем как chr-код
			putbits(*position, 8, fileout); //записываем чар код
			position++;
			srcleng--;
			pointer++;
		}
	}
	putbits(0, 8, fileout);
	printf("\nCompress compleated!\n", fileleng);
}
//Разархивирование Алгоритм  LZ77
int getbits(int nbits, char filein[])     //функция считывания
{
	static int bitcounter = 8;
	static int indata = 0;
	int bit, data = 0;
	FILE *in = fopen(filein, "r");
	for (; nbits > 0; nbits--)
	{
		if (bitcounter == 8)
		{
			bitcounter = 0;
			indata = getc(in);
		}

		if (indata == EOF)
		{
			printf("Error writing to First file.");
			return -6;
		}
		bit = (indata & 0x80) ? 1 : 0;
		data <<= 1;
		data += bit;
		bitcounter++;
		indata <<= 1;
	}
	return data;
}

void decompress_stud(char *filein, char *fileout)       //функция извлечения
{
	unsigned char  *pos;
	int   i, dist, ch, maxleng;
	printf("Decompress started.\n");
	// Получаем длину исходного файла
	FILE *in = fopen(filein, "r");
	FILE *out = fopen(fileout, "w");
	read(fileno(in), &fileleng, sizeof(long));
	pos = srcstart;
	while (fileleng > 0)
	{
		if ((ch = getbits(1, filein)) == 0) // Если chr-код, копируем в буфер текста символ 
		{
			ch = getbits(8, filein);
			putc(ch, out);
			*pos = ch;
			pos++;
			fileleng--;
		}
		else // Иначе - копируем maxleng символов из словаря, начиная с позиции dist
		{
			dist = getbits(DICBITS, filein) + 1;
			maxleng = getbits(STRBITS, filein) + THRESHOLD + 1;
			for (i = 0; i < maxleng; i++)
			{
				*(pos + i) = *(pos + i - dist);
				putc(*(pos + i - dist), out);
			}
			pos += maxleng;
			fileleng -= maxleng;
		}
		if (pos > srcstart + TEXTSIZE) // Если буфер заполнен, записываем его на диск и сдвигаем словарь в начало буфера
		{
			memcpy(srcbuf, pos - DICSIZE, DICSIZE);
			pos = srcstart;
		}
	}
	printf("\nDecompress compleated.");
}

int main() 
{
	char mode;
	char fname_in[20];
	char fname_out[20];
	char cod[] = "zzblabzzlabla";
	crc16("input.txt");
	puts("Enter '1' to encode or '2' to decode");
	scanf("%c", &mode);
	if (mode == '1') 
	{
		puts("Enter file names");
		scanf("%s %s", fname_in, fname_out);
		compress_stud(fname_in, "out");
		coding("out", fname_out, cod, 1);
		remove("out");
		printf("CRC-16(%s):%X CRC-16(%s):%X\n", fname_in, crc16(fname_in), fname_out, crc16(fname_out));
		puts("Encoding completed");
	}
	else 
	{
		puts("Enter file names");
		scanf("%s %s", fname_in, fname_out);
		coding(fname_in, "out", cod, -1);
		decompress_stud("out", fname_out);
		remove("out");
		printf("CRC-16(%s):%X CRC-16(%s):%X\n", fname_in, crc16(fname_in), fname_out, crc16(fname_out));
		puts("Decoding completed");
	}
	return 0;
}
_____
Код программы нужно выделять (форматировать) тегами [CODE] (читать FAQ)
Модератор

Последний раз редактировалось Serge_Bliznykov; 27.03.2018 в 13:43.
Татьяна12345678 вне форума Ответить с цитированием
Старый 21.03.2018, 16:32   #2
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Здравствуйте, у меня появилось несколько вопросов:
1) Какой бюджет проекта?
2) В какой среде пишете? Подойдет ли Вам C++Builder 6?
3) Подойдут ли Вам при расчетах Яндекс.Деньги?
4) Какие ошибки в программе?
5) Эта программа для студенческих целей? Т.е. обучение, школа и т.д.
6) Поставьте тэги кода, пожалуйста.
7) И вышлите еще файлы к этому проекту: "input.txt", входной файл, выходной файл и т.д. мне на почту: sergeisky@yahoo.com.
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.

Последний раз редактировалось Cuprum5; 21.03.2018 в 17:40. Причина: Добавил фразу.
Cuprum5 вне форума Ответить с цитированием
Старый 21.03.2018, 18:50   #3
alexcoder
Форумчанин
 
Регистрация: 31.05.2009
Сообщений: 786
По умолчанию

Татьяна12345678, обращайтесь e-mail: informatik101@mail.ru vk.com/alexcoder1
Помощь с программами:
vk.com/alexcoder1
e-mail: informatik101@mail.ru
alexcoder вне форума Ответить с цитированием
Старый 21.03.2018, 20:23   #4
DeveloperC
 
Регистрация: 24.02.2018
Сообщений: 6
По умолчанию

Татьяна E-mail matersoft@inbox.ru дам готовый код под MSVC 2010 - 2017, я давно это применяю в своем крипторе
DeveloperC вне форума Ответить с цитированием
Старый 27.03.2018, 13:18   #5
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Этот код косячный до безобразия. Я хотел осилить эту программу, но в последний момент отказался. Читая про LZ-77, я заметил что повторяющиеся строки кодируются так:
Берутся 3 элемента:
<1, 2, 3>
1 - это сколько символов нужно отступить назад;
2 - сколько символов берется из того места;
3 - последний заканчиваемый символ - вот это вот зачем?????????? Неужели нельзя его просто поставить и все, вот это выбесило и дальше я работать не стал.

А в Вашем коде Танюха, глюков очень много и исправлять его - это себя неуважать. Вот в этой строке косяк: программа просто не может прочитать файл, потому что переменные srcstart + offset обе равны 0. Это косяк, потому что функция fread(1, 2, 3, 4) в первом параметре должна иметь указатель - на начало массива, а его здесь нет поэтому ничего не читается, ничего не кодируется и т.д.
Цитата:
Сообщение от Татьяна12345678 Посмотреть сообщение
Код:
while((srcleng = fread(srcstart + offset, 1, TEXTSIZE, in))>0)

// Перенёс данное сообщение из закрытой темы.
// Обращаю внимание, что тут раздел "фриланс"
// Модератор.
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.

Последний раз редактировалось Serge_Bliznykov; 27.03.2018 в 13:45.
Cuprum5 вне форума Ответить с цитированием
Старый 28.03.2018, 08:12   #6
Larboss
Недо
Участник клуба
 
Регистрация: 11.08.2011
Сообщений: 1,394
По умолчанию

Пишите: larbossfreelance@yandex.ru

Есть оригинальное задание? Или код откуда-то скопирован.
С помощью программирования можно разбогатеть и изменить мир к лучшему (с) Бьерн Страуструп
Larboss вне форума Ответить с цитированием
Старый 28.03.2018, 08:15   #7
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Код скопирован с Киберфорума, но правда вчера я его не нашел. А раньше находил.:D
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.
Cuprum5 вне форума Ответить с цитированием
Старый 28.03.2018, 15:49   #8
Black Fregat
Программист
Участник клуба
 
Аватар для Black Fregat
 
Регистрация: 23.06.2009
Сообщений: 1,772
По умолчанию

Цитата:
Сообщение от Cuprum5 Посмотреть сообщение
вчера я его не нашел.
Плохо искали. Но там же написано, что изначально ноги растут от Википедии
Black Fregat вне форума Ответить с цитированием
Старый 28.03.2018, 19:51   #9
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Black Fregat, дадите ссылку?
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.
Cuprum5 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сжатие файла методом Хаффмана на PHP Valtasaar Помощь студентам 2 28.11.2015 13:34
Сжатие данных GreenWizard Общие вопросы по программированию, компьютерный форум 0 19.12.2012 13:06
Сжатие данных Horknee Свободное общение 18 10.05.2010 11:21
Сжатие информации методом Хаффмана на С++ BaSoff Общие вопросы C/C++ 3 18.11.2009 19:51