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

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

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 29.05.2009, 01:20   #1
gosu
 
Регистрация: 29.05.2009
Сообщений: 7
По умолчанию Разбиение текста на блоки.

народ , помогите плс

Вкратце: задание по криптографии - написать программу шифрования / дешифрования сети Фейстеля с четырьмя ветвями.

Текст, считываемый из файла, разбивается на 4 равных блока и дальше с полученными блоками уже выполняются операции.

Так вот, пусть текст будет заданной длины в 512 символов.
Я хотел разбить весь текст на 4 массива по 128 символов каждый.
Попытался сделать следующее:

Код:
FILE * OpenTextFile;
char BuferFrom[ 514 ];

OpenTextFile = fopen ( "OT.txt", "rb" );
fgets( BuferFrom, 513, OpenTextFile );
char *Part1, *Part2, *Part3, *Part4;
char Block1[ 129 ], Block2[ 129 ], Block3[ 129 ], Block4[ 129 ];


Part1 = Part2 = Part3 = Part4 = BuferFrom;
Part1 = Part1 + 0;
Part2 = Part2 + 128;
Part3 = Part3 + 256;
Part4 = Part4 + 384;
strncpy( Block1, Part1, 128 );
strncpy( Block2, Part2, 128 );
strncpy( Block3, Part3, 128 );
strncpy( Block4, Part4, 128 );
И в итоге получилось, что только Block3 и Block4 содержат нужное, т.е. 128, символов.
Остальные блоки по 260+.
Если функции strncpy явно указано, что она должна копировать только 128 символов, почему она копирует больше?
Может быть можно как-то более "эффектно" это сделать?
И ещё: когда записываю один из блоков в файл, то в конце появляются крокозябры. Что это?
Это значит, что в массиве не указан символ конца строки '\0'?

P.S. заранее спасибо

Последний раз редактировалось gosu; 29.05.2009 в 01:39.
gosu вне форума Ответить с цитированием
Старый 29.05.2009, 01:39   #2
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

Раз вы открываете файл как бинарный, то читайте лучше так:
Код:
fread(BuferFrom,512,sizeof(char),OpenTextFile);
Собственно, вот так сделал. Выводит то, что надо:
Код:
#include <stdio.h>
#include <conio.h>
#include <string.h>

int main()
{
FILE * OpenTextFile;
char BuferFrom[ 514 ];
char *Part1, *Part2, *Part3, *Part4;
char Block1[ 129 ], Block2[ 129 ], Block3[ 129 ], Block4[ 129 ];

OpenTextFile = fopen ( "OT.txt", "rb" );
//fgets(BuferFrom, 513, OpenTextFile );
fread(BuferFrom,512,sizeof(char),OpenTextFile);

Part1 = Part2 = Part3 = Part4 = BuferFrom;
Part1 = Part1 + 0;
Part2 = Part2 + 128;
Part3 = Part3 + 256;
Part4 = Part4 + 384;

strncpy(Block1, Part1, 128 );
Block1[128] = 0;
strncpy(Block2, Part2, 128 );
Block2[128] = 0;
strncpy(Block3, Part3, 128 );
Block3[128] = 0;
strncpy(Block4, Part4, 128 );
Block4[128] = 0;

printf("%s\n\n%s\n\n%s\n\n%s\n\n",Block1,Block2,Block3,Block4);
fclose(OpenTextFile);

getch();
return 0;
}
Цитата:
И ещё: когда записываю один из блоков в файл, то в конце появляются крокозябры. Что это?
Это значит, что в массиве не указан символ конца строки '\0'?
Да.
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 31.05.2009, 15:55   #3
gosu
 
Регистрация: 29.05.2009
Сообщений: 7
По умолчанию

Спасибо за столь быстрый ответ=)
Всё работает отлично.
А есть ещё способы с Вами связаться? Не могли бы Вы мне в ICQ написать?
gosu вне форума Ответить с цитированием
Старый 31.05.2009, 16:02   #4
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

gosu, аси нет.
Обращайтесь на форум и вам кто-нибудь поможет.
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 01.06.2009, 03:18   #5
gosu
 
Регистрация: 29.05.2009
Сообщений: 7
По умолчанию

Жаркая погода, девушки в юбочках на улице... В общем, мозг соображает слабо, а время поджимает=(

Столкнулся ещё с одной проблемой - это сам процесс шифрования.

Описание самого метода:
Сеть Фейстеля

Но шифрование выполняется по данной модификации:
Картинка тык=), где:
X1 - X4 - блоки текста, которые в программе заданы как Block1- Block4;
Y1 - Y4 - блоки текста, полученные после шифрования;
F ( на рисунке ) - любая обратимая функция, которая должна принимать в виде "аргументов" некий "ключ" и первый блок текста Block1, потом изменённый блок складывается с помощью операции сложение по модулю 2 со вторым блоком текста. Сложение по модулю два - обратимая функция, поэтому получается, что в программе используем её дважды
После этих операций НЕизменённый X1 записывается на место Y4, X2 -> Y1, X3 -> Y2 и X4 -> Y3;

Весь этот процесс называется раундом сети Фейстеля.

Выше приведён листинг, который разбивает весь текст на 4 равных блока.
Ещё можно оговорить одно условие, дабы упростить программу: открытый текст и шифр текст должны содержать только заглавные буквы русского язык { А-Я }, ни пробелов, ни других символов.
Для этого я создал массив, который содержит численные значения букв русского языка. Да, можно было использовать встроенную кодировку, но что-то не пришло в голову, как её ограничить тем, чтобы она при расчётах не выходила за рамки русского алфавита...

AnsiString AlphArray[ 2 ][ 32 ] ={
{ "А", "Б", "В", "Г", "Д", "Е", "Ж", "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ы", "Ь", "Ъ", "Э", "Ю", "Я" },
{ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31" }
};

Для одного раунда я хотел написать функцию, вроде такой:
blocki - переменная, которая пробегается по каждому символу в блоках, с которыми производятся операции.
int rKey - "ключ" раунда, который будет вводиться пользователем через поле TEdit.

for( int blocki = 0; blocki <= 128; blocki ++ )
{
for( int i = 0; i <= 32; i++ )
{
if( Block1[ blocki ] == AlphArray[ 0 ][ i ] )
{
Block1[ blocki ] = AlphArray[ 0 ][ i ] ^ rKey; // Здесь получаем число из AlphArray, которое соотвует букве Block1[ blocki ] и складываем по модулю 2 с ключем раунда.
Block2[ blocki ] = Block2[ blocki ] ^ Block1[ blocki ]; // Здесь тоже int.
Block2[ blocki ] = Block2[ blocki ] Mod 32; // 32 - кол-во символов в алфавите. Иначе не попадаем в тот алфавит, который мы указали выше.
}
}
}
Функция должна возвращать изменённый Block2, причём должен содержать символы русского языка... А принимает значения двух блоков и ключ раунда.

Сначала делал просто, без задания своего алфавита. В результате получал нормальную первую половину алгоритма шифрования, где Block1[ blocki ] ^ rKey; когда же я складывал первый изменённый блок со вторым блоком текста, получалось всего 5-8 крокозябр

Вот такая задача, вроде элементарная но не хватка этих самых элементарных знаний даёт о себе знать

Если коротко, то вопрос в том: Как из char перевести в int, выполнить две операции сложения по модулю 2, а затем снова из int перевести в char, который бы не выходил за рамки заглавных букв русского алфавита?

Пробовал через atoi и itoa, но каждый раз получал ошибку, связанную с типами данных...
gosu вне форума Ответить с цитированием
Старый 01.06.2009, 03:26   #6
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

Цитата:
сли коротко, то вопрос в том: Как из char перевести в int, выполнить две операции сложения по модулю 2, а затем снова из int перевести в char, который бы не выходил за рамки заглавных букв русского алфавита?
Ну так char, по сути, и есть число. atoi не нужна. Используйте явное приведение.

Код:
char c='a'; // символ 'a'
int k;

k = (int)c;  // получаем код символа. Теперь k == 97
k = k+1;   // для примера прибавляем единицу
c = (char)k;  // приводим обратно в char. Символ с кодом 98 - 'b'
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 01.06.2009, 03:41   #7
gosu
 
Регистрация: 29.05.2009
Сообщений: 7
По умолчанию

Да, но тогда и массив AlphArray надо указывать в типе char, но это у меня приводило к ошибке: cannot conver "char * *" to "char *".
И как всё-таки ввести ограничение только на заглавные буквы русского алфавита?
gosu вне форума Ответить с цитированием
Старый 01.06.2009, 03:51   #8
Sazary
В тени
Старожил
 
Аватар для Sazary
 
Регистрация: 19.12.2008
Сообщений: 5,788
По умолчанию

Цитата:
Да, но тогда и массив AlphArray надо указывать в типе char,
Хм.. Только сейчас заметил, что у вас двумерный массив строк. А зачем?
Сделайте так:
Код:
AnsiString AlphArray="АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ";
Вот вам и массив символов.
Вполне очевидно, чтобы что-то понять, необходимо книги читать.
Не нужно плодить бессмысленных тем. Вас Поиск избавит от многих проблем.

___________________________________ ___________________________________ _______
[=Правила форума=]_____[Поиск]_____[Литература по С++]____[Литература. Паскаль]
Sazary вне форума Ответить с цитированием
Старый 01.06.2009, 08:31   #9
gosu
 
Регистрация: 29.05.2009
Сообщений: 7
По умолчанию

Да, что-то с массивом я намудрил, присвоив лишний индекс, который соответствует первому...
gosu вне форума Ответить с цитированием
Старый 01.06.2009, 21:40   #10
gosu
 
Регистрация: 29.05.2009
Сообщений: 7
По умолчанию

Как можно сделать сортировку в одном из столбцов поля TValueListEditor, чтобы изменялся и первый столбец? Или же использовать вообще другой компонент.

Надо провести частотый анализ текста, скажем, у нас получился результат:
А 0,012
Б 0,004
В 0,044

Надо упорядочить так:
В 0,044
А 0,012
Б 0,004


Буквы - первый столбец, частота их встречь в тексте - второй.
gosu вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Блоки div вместо td, как сделать две колонки одинаковой высоты? v.victoria12345 HTML и CSS 0 06.05.2009 18:05
Разбиение записей Лубышев Microsoft Office Access 0 17.03.2009 08:27
как сформировать проверку (вложенные блоки) Tanuska___:) Общие вопросы Delphi 3 25.11.2008 14:11
Разбиение исходника на части SimaoO Общие вопросы C/C++ 2 16.11.2008 15:08
Разбиение на части MAcK Общие вопросы .NET 4 18.09.2008 13:56