![]() |
1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!
![]() ![]() |
![]() |
18192123 |
![]()
Сообщение
#1
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Задание состоит в следующем:
Написать программу, реализующую алгоритм потокового шифрования содержимого текстового или двоичного файла. Программа должна запрашивать имя входного и выходного файлов, представление образующего многочлена и инициализирующее значение. Разрядность РСЛОС должна быть меньше или равной максимальной разрядности стандартных целочисленных типов данных (64 бит). Вот на чём основываюсь (см. прикреплённый документ).. Как я поняла, основная задача - сгенерировать поток ключей..для этого и применяется РСЛОС (регистр сдвига с линейной обратной связью).. Есть некоторые вопросы по реализации: Пусть пользователь ввёл представление образующего многочлена, инициализирующее значение.. Используя эту информацию нужно некоторый n-битный регистр сдвига обинициализировать (и первый вопрос: как это осуществить?? что за инициализирующее значение задавать??)..чтоб в дальнейшем получать новый бит, выполняя XOR над определёнными битами.. Объясните, пожалуйста! Эскизы прикрепленных изображений ![]() |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
Ну, так у тебя основное-то как раз и не написано... Вот тут лежит более развернутое объяснение, даже с фрагментами кода на С: http://www.ssl.stu.neva.ru/psw/crypto/potok/str_ciph.htm#top (тебе надо смотреть главу 2 - "Строительные блоки для создания криптосхем"). К сожалению, у меня PDF не открываются как положено, кричит, что нет какого-то шрифта в системе. Возможно у тебя с этим все в порядке. Если нет - то в кэше Гугла есть текст этого документа: Здесь
Я надеюсь, это поможет тебе разобраться... |
18192123 |
![]()
Сообщение
#3
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Спасибо за ссылки!
Насколько я поняла, с помощью функции LFSR() мы и будем получать новый бит регистра..
int LFSR()
{
static unsigned long ShiftRegister = 1 ;
/* Все кроме 0 */
ShiftRegister = ( ( ( ( ShiftRegister >> 31)
^ ( ShiftRegister >> 6)
^ ( ShiftRegister >> 4)
^ ( ShiftRegister >> 2)
^ ( ShiftRegister >> 1)
^ ( ShiftRegister ) )
& 0x00000001 )
<< 31)
| ( ShiftRegister >> 1) ;
return ShiftRegister & 0x00000001 ;
}
Т.е. теперь всё готово, чтобы выполнить XOR для бита из открытого текста и этого полученного нового бита регистра?? Я правильно поняла? Если да, то ещё вопрос: объясните пожалуйста, как получить очерёдный бит из открытого текста для последующего XOR? (причём открытый текст запрашивается из файла) |
volvo |
![]()
Сообщение
#4
|
Гость ![]() |
Может, проще будет забрать сразу 8 бит регистра сдвига, "сложить" их в байт, и потом XOR-ить с очередным байтом из файла (или потока)? Ну, если нет, так нет, можно и побитово сделать, просто мороки чуть больше...
|
18192123 |
![]()
Сообщение
#5
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
|
volvo |
![]()
Сообщение
#6
|
Гость ![]() |
Цитата что имеется в виду под "сложить" их в байт? Вот это:unsigned char byte = 0;
for(int i = 0; i < 8; i++) {
byte <<= 1;
byte |= (unsigned char)LFSR();
}
В переменной byte получишь 8 бит ключа, записанных слева направо... Если надо справа налево - тогда:unsigned char byte = 0;
for(int i = 0; i < 8; i++) {
byte |= ((unsigned char)LFSR() << i);
}
(вроде нигде не накосячил, пишу прямо здесь, так что все проверяй...) |
18192123 |
![]()
Сообщение
#7
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Читаю символ из файла, потом идёт формирование байта ключа.. дальше XOR для получения шифртекста.. Проблема следующая: каким бы не было инициализирующее значение, результат один и тот же: для одного и того же открытого текста, один и тот же шифртекст..
int LFSR(unsigned long ShiftRegister)
{
/* Все кроме 0 */
ShiftRegister = ( ( ( ( ShiftRegister >> 31)
^ ( ShiftRegister >> 6)
^ ( ShiftRegister >> 4)
^ ( ShiftRegister >> 2)
^ ( ShiftRegister >> 1)
^ ( ShiftRegister ) )
& 0x00000001 )
<< 31)
| ( ShiftRegister >> 1) ;
return ShiftRegister & 0x00000001 ;
}
void __fastcall TFormMain::Button1Click(TObject *Sender)
{
unsigned long ShiftRegister;
unsigned char ch;
FILE *INfile, *OUTfile;
char *filenameIn=OpenDialog1->FileName.c_str();
char *filenameOut=SaveDialog1->FileName.c_str();
INfile=fopen(filenameIn, "r");
OUTfile=fopen(filenameOut, "w");
ShiftRegister=StrToInt(LabEdInitial->Text); // считываем инициализирующее значение
unsigned char byte = 0;
while (!feof(INfile))
{
fread(&ch,sizeof(unsigned char),1,INfile);
for(int i = 0; i < 8; i++)
{
byte |= (unsigned char)LFSR(ShiftRegister);
byte <<= 1;
}
for(int i = 0; i < 8; i++)
{
byte ^= ch;
byte <<= 1;
}
int count=fwrite(&byte,sizeof(unsigned char),1,OUTfile);
Memo1->Lines->Add(byte);
}
}
Объясните пожалуйста, где я не права? |
volvo |
![]()
Сообщение
#8
|
Гость ![]() |
Цитата где я не права? 1) зачем понадобилось менять LFSR, да еще таким образом, как ты это сделала? 2) считала 8 бит из LFSR, один байт из файла, отXOR-ила их, и продолжаешь... Не надо XOR-ить 8 раз... Вот это отработало, как ожидалось: unsigned long ShiftRegister = 1;
int LFSR()
{
/* Все кроме 0 */
ShiftRegister = ( ( ( ( ShiftRegister >> 31)
^ ( ShiftRegister >> 6)
^ ( ShiftRegister >> 4)
^ ( ShiftRegister >> 2)
^ ( ShiftRegister >> 1)
^ ( ShiftRegister ) )
& 0x00000001 )
<< 31)
| ( ShiftRegister >> 1) ;
return ShiftRegister & 0x00000001 ;
}
void __fastcall TForm1::Button6Click(TObject *Sender)
{
unsigned char ch;
FILE *INfile, *OUTfile;
AnsiString filenameIn, filenameOut;
if(OpenDialog1->Execute()) {
filenameIn = OpenDialog1->FileName;
}
if(SaveDialog1->Execute()) {
filenameOut = SaveDialog1->FileName;
}
INfile = fopen(filenameIn.c_str(), "r");
OUTfile = fopen(filenameOut.c_str(), "w");
ShiftRegister = StrToInt(Edit2->Text); // считываем инициализирующее значение
unsigned char byte = 0;
while (!feof(INfile))
{
fread(&ch,sizeof(unsigned char),1,INfile);
for(int i = 0; i < 8; i++)
{
byte |= (unsigned char)LFSR();
byte <<= 1;
}
byte ^= ch; // <--- Вот XOR который я упустил
int count = fwrite(&byte, sizeof(unsigned char), 1, OUTfile);
Memo1->Lines->Add(byte);
}
}
Сообщение отредактировано: volvo - 17.02.2009 22:44 |
18192123 |
![]()
Сообщение
#9
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Спасибо за разъяснение!!
Но один вопрос... Я не правильно делала XOR между байтом открытого текстом и 8-мью битами LFSR? Просто я не вижу ничего похоже на этот этап в последнем приведённом коде.. |
volvo |
![]()
Сообщение
#10
|
Гость ![]() |
Да, я упустил одну строчку... Добавил в программу выше.
|
18192123 |
![]()
Сообщение
#11
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
В процессе тестирования появился ещё вопрос..
По идее, если с помощью написанной программы мы получили шифртекст, то если запустить снова программу и работать с шифртекстом, то по итогам работы программы в выходном файле мы получим исходный открытый текст (на основе которого получили используемый шифртекст).. Так оно и есть..почти..всегда в конце файла при таком порядке действий появляются два лишние символа, которых нет в открытом тексте.. Объясните пожалуйста, в чём может быть причина?? |
volvo |
![]()
Сообщение
#12
|
Гость ![]() |
Читаешь исходный файл без контроля ошибок. Добавь этот контроль:
while (!feof(INfile))
{
if(fread(&ch,sizeof(unsigned char),1,INfile)) { // вот этот if и делает свое дело ...
for(int i = 0; i < 8; i++)
{
byte |= (unsigned char)LFSR();
byte <<= 1;
}
byte ^= ch;
int count = fwrite(&byte, sizeof(unsigned char), 1, OUTfile);
Memo1->Lines->Add(byte);
}
}
Теперь из файла будет считываться и обрабатываться ровно столько символов, сколько там есть, а не на 1 больше... При обратном преобразовании - аналогично... Вот тебе и лишние 2 символа... |
18192123 |
![]()
Сообщение
#13
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Большое спасибо!!
Теперь хочу добиться того, чтобы пользователь мог вводить представление многочлена, а не только использовать тот, который прописан на данный момент в функции LFSR.. Вот мои попытки:
int LFSR(TMemo *MemoPolinom)
{
int i=0;
for (int i=0; i<=MemoPolinom->Lines->Count; i++)
{
ShiftRegister ^=(ShiftRegister>>StrToInt(MemoPolinom->Lines->Strings[i]));
}
ShiftRegister&=0x00000001;
ShiftRegister>>StrToInt(MemoPolinom->Lines->Strings[0]);
ShiftRegister|=( ShiftRegister >> 1);
/*ShiftRegister = ( ( ( ( ShiftRegister >> 31)
^ ( ShiftRegister >> 6)
^ ( ShiftRegister >> 4)
^ ( ShiftRegister >> 2)
^ ( ShiftRegister >> 1)
^ ( ShiftRegister ) )
& 0x00000001 )
<< 31)
| ( ShiftRegister >> 1) ;
*/
return ShiftRegister & 0x00000001 ;
}
В итоге программа вылетает на строчке
byte |= (unsigned char)LFSR(MemoPolinom);
с ошибкой "is not a valid integer value" (в MemoPolinom вводила: 31 6 4 2 1 0 ) Скажите пожалуйста, как исправить...? |
volvo |
![]()
Сообщение
#14
|
Гость ![]() |
У тебя тут 2 ошибки:
1) неравенство НЕстрогое, элемента с индексом Count в StringList-е нет, есть от 0 до Count - 1... 2) не заметила, что в прежней реализации ВСЕ сдвиги и XOR-ы производились со старым значением ShiftRegister, и только в самом конце ему присваивалось новое значение?... А сейчас ты на каждой итерации меняешь значение? Не пойдет... Вот так надо: int LFSR(TMemo *MemoPolinom)
{
int i=0;
unsigned long uL = StrToInt(MemoPolinom->Lines->Strings[i]);
for (int i = 1; i < MemoPolinom->Lines->Count; i++) {
uL ^= (ShiftRegister >> StrToInt(MemoPolinom->Lines->Strings[i]));
}
uL &= 0x00000001;
uL <<= StrToInt(MemoPolinom->Lines->Strings[0]); // Здесь ты вообще непонятно что делала...
uL |= (ShiftRegister >> 1);
ShiftRegister = uL;
return ShiftRegister & 0x00000001 ;
}
|
18192123 |
![]()
Сообщение
#15
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Спасибо большое за разъяснение!!
|
18192123 |
![]()
Сообщение
#16
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Здравствуйте!
У меня вот такой вопрос: с помощью OpenDialog пользователь выбрал текстовый файл с исходным сообщением, а можно ли по нажатию кнопки в разрабатываемом приложении открыть выбранный файл для просмотра содержимого?? Пробовала с помощью CreateProcess..не получилось (даже прописав путь ручками, а не взяв из OpenDialog)..наверно этот вариант не подходит..
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(NULL,"H:\\files\\1.txt", NULL, NULL, FALSE,NULL, NULL, NULL, & si, & pi);
|
volvo |
![]()
Сообщение
#17
|
Гость ![]() |
Зачем здесь CreateProcess? Можно же открыть средствами Shell-а:
ShellExecute(NULL, "open", OpenDialog1->FileName.c_str(), 0, 0, SW_SHOWNORMAL);
, только надо убедиться, что файл действительно был выбран, иначе результат будет несколько... неожиданным, что-ли... Хотя на самом деле - логичным. |
18192123 |
![]()
Сообщение
#18
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
В процессе тестирования наткнулась на ошибки...
Если в качестве исходного сообщения брать текст на русском, то часть букв при расшифровке исчезает... Например: Исх. сообщение: Для того чтобы конкретный РСЛОС имел максимальный период (т.е. циклически проходил через все 2n-1 внутренних состояний), многочлен, образованный из отводной последовательности, должен быть примитивным (неприводимым) – т.е. не раскладываться на произведение двоичных многочленов меньшей степени. Некоторые неприводимые двоичные многочлены приведены в табл. 1.1. Перед запуском РСЛОС при зашифровании или расшифровании, регистр необходимо инициализировать одним и тем же значением Закодировала, получила шифртекст. Для раскодирования прогоняю полученный шифртекст через приложение, получаю: Для того чтобы конкретный РСЛОС имел максимальный перио и это всё, что осталось... Брала инициализирующее значение 1, многочлен 32, 7, 5, 3, 2, 1, 0 Скажите пожалуйста, в чём может быть причина происходящего?? Прикрепленные файлы ![]() |
volvo |
![]()
Сообщение
#19
|
Гость ![]() |
Цитата в чём может быть причина происходящего?? Ну, скорее всего в том, что надо открывать файлы, как бинарные: INfile=fopen(filenameIn, "rb");
OUTfile=fopen(filenameOut, "wb");
, все остальное вроде правильно... |
18192123 |
![]()
Сообщение
#20
|
![]() Профи ![]() ![]() ![]() ![]() Группа: Пользователи Сообщений: 920 Пол: Женский Реальное имя: Марина Репутация: ![]() ![]() ![]() |
Ну, скорее всего в том, что надо открывать файлы, как бинарные.. Спасибо! Исправила, с тем примером заработало. Ещё хотела спросить насчёт такого многочлена: 60,1,0.. Брала иниц. значение=1, в итоге шифртекст совпал с открытым (брала разные примеры текстов)..Скажите пожалуйста, это из-за реализации алгоритма или причина в чём-то другом? |
![]() ![]() |
![]() |
Текстовая версия | 28.07.2025 11:52 |