Форум «Всё о Паскале» _ Задачи _ Программа не работает, помогите исправить
Автор: Cherry225 20.10.2016 23:14
Программа не работает, помогите исправить.
Задача: открытый текст записывается в матрицу по определенному ключу k1, определяющему порядок записи открытого текста в строки матрицы при шифровании. Шифртекст образуется при считывании из этой матрицы по ключу k2, определяющему, в каком порядке записывается информация из столбцов матрицы. Для реализации такого варианта перестановки можно не использовать непосредственно матрицу, а осуществлять перерасчет коэф- фициентов.
Код
var q, h: array of integer;
Text, Text_1, Text_2, text_3, S: String;
i, j, kolsimvolov: integer; key1: array of Byte; key2: array of Byte; p, m,t: Boolean; r, b: integer; Textmatr: Array of array of Char;
repeat Write('введите текст для кодировки: '); Readln(Text); kolsimvolov:=Length(text); m:=True; if kolsimvolov>r*b then m:=False; if not(m) then writeln('Кол-во символов не должно привышать r*b '); until m; If (kolsimvolov div (r*b))<> 1 then begin text:=text+' '; Inc(kolsimvolov); end; Repeat Writeln('Введите ключ 1 , состоящий из ',r,' символов, через "Enter"'); for i:=1 to r do Readln(key1[i]); p:=true; for i:=1 to r-1 do if (key1[i]=key1[i+1]) then p:=false; If Not(p) then writeln('Все символы должны быть различны!'); Until p; Repeat Writeln('Введите ключ 2, состоящий из ',b,' символов, через "Enter"'); for i:=1 to b do Readln(key2[i]); t:=true;
for i:=1 to b-1 do if (key2[i]=key2[i+1]) then t:=false; If Not(t) then writeln('Все символы должны быть различны!');
Until t; Writeln; //----------------------------------------------------— For i:=1 to r do For j:=1 to b do Textmatr[key1[i],j]:=Text[(i-1)*b+j]; Writeln(' k1\k2 '); For i:=1 to r do begin Write(' ',i,' '); For j:=1 to b do write(' ',textmatr[i,j],' '); Writeln; end; //----------------------------------------------------— Text_1:=''; For j:=1 to b do for i:=1 to r do begin S:=textmatr[i,key2[j]]; Text_1:=Text_1+S; end; Writeln('Закодированный текст:',' ',text_1); //-----------------------------------------------------— Text_2:=''; For j:=1 to b do begin S:=Copy(Text_1,(key2[j]-1)*r+1,r); Text_2:=Text_2+S; end; Text_3:=''; For i:=1 to r do For j:=1 to b do begin S:=Copy(Text_2,(j-1)*r+key1[i],1); Text_3:=Text_3+S; end; Writeln('Раскодированный текст:',' ',Text_3); //-----------------------------------------------------— Writeln; Readln; End.
Автор: Федосеев Павел 21.10.2016 2:18
А как не работает?
Автор: Cherry225 21.10.2016 12:53
Цитата(Федосеев Павел @ 21.10.2016 4:18)
А как не работает?
После ввода ключей программа вылетает . Должно получиться как на картинке
Автор: OCTAGRAM 21.10.2016 14:39
Чтобы происходящее было более понятно, лучше включить проверку диапазонов в настройке проекта или директивой {$R+}. Правда, по моему опыту, некоторые версии Delphi ошибочно не проверяли диапазон динамического массива, так что не гарантирует.
У вас в SetLength для TextMatr только один размер указан.
Автор: Cherry225 21.10.2016 15:25
Цитата(OCTAGRAM @ 21.10.2016 16:39)
Чтобы происходящее было более понятно, лучше включить проверку диапазонов в настройке проекта или директивой {$R+}. Правда, по моему опыту, некоторые версии Delphi ошибочно не проверяли диапазон динамического массива, так что не гарантирует.
У вас в SetLength для TextMatr только один размер указан.
Я исправила, но все равно не работает
Код
var q, h: array of integer;
Text, Text_1, Text_2, text_3, S: String;
i, j, kolsimvolov: integer; key1: array of Byte; key2: array of Byte; p, m,t: Boolean; r, b: integer; Textmatr: Array of array of Char;
repeat Write('введите текст для кодировки: '); Readln(Text); kolsimvolov:=Length(text); m:=True; if kolsimvolov>r*b then m:=False; if not(m) then writeln('Кол-во символов не должно привышать r*b '); until m; If (kolsimvolov div (r*b))<> 1 then begin text:=text+' '; Inc(kolsimvolov); end; Repeat Writeln('Введите ключ 1 , состоящий из ',r,' символов, через "Enter"'); for i:=0 to r-1 do Readln(key1[i]); p:=true; for i:=0 to r-1 do if (key1[i]=key1[i+1]) then p:=false; If Not(p) then writeln('Все символы должны быть различны!'); Until p; Repeat Writeln('Введите ключ 2, состоящий из ',b,' символов, через "Enter"'); for i:=0 to b-1 do Readln(key2[i]); t:=true;
for i:=0 to b-1 do if (key2[i]=key2[i+1]) then t:=false; If Not(t) then writeln('Все символы должны быть различны!');
Until t; Writeln; //----------------------------------------------------— For i:=0 to r-1 do For j:=0 to b-1 do BEGIN //OutPutDebugString(PWideChar(inttostr(i)+' '+inttostr(j))); Textmatr[key1[i]-1,j]:=Text[(i)*b+j+1]; END; Writeln(' k1\k2 '); For i:=0 to r-1 do begin Write(' ',i,' '); For j:=0 to b-1 do write(' ',textmatr[i,j],' '); Writeln; end; //----------------------------------------------------— Text_1:=''; For j:=0 to b-1 do for i:=0 to r-1 do begin S:=textmatr[i,key2[j]-1]; Text_1:=Text_1+S; end; Writeln('Закодированный текст:',' ',text_1); //-----------------------------------------------------— Text_2:=''; For j:=0 to b-1 do begin S:=Copy(Text_1,(key2[j]-1)*r+1,r); Text_2:=Text_2+S; end; Text_3:=''; For i:=0 to r-1 do For j:=0 to b-1 do begin S:=Copy(Text_2,(j-1)*r+key1[i],1); Text_3:=Text_3+S; end; Writeln('Раскодированный текст:',' ',Text_3); //-----------------------------------------------------— Writeln; Readln; End.
Автор: Федосеев Павел 21.10.2016 17:53
Вот читаю сообщение студента: "После ввода ключей программа вылетает . Должно получиться как на картинке". Куда "вылетает"?
При вводе строки для шифрования лучше так вместо нескольких строк.
m := (kolsimvolov <= r * b);
Потом, что делают эти строки?
if (kolsimvolov div (r * b)) <> 1 then begin Text := Text + ' '; Inc(kolsimvolov); end;
Проверка уникальности номеров ключа (ключей) - двумя циклами
for i:=0 to r-1 do for j:=i+1 to r-1 do if (key1[i] = key1[j]) then p := False;
Пока это - исправляйте. Кроме того - уважайте преподавателя и нас - воспользуйтесь форматтером исходного кода http://forum.pascal.net.ru/index.php?showtopic=24653#. У этого форматтера особенность - обязательно в начале должна присутствовать строка program.
Добавлено через 8 мин. Плюс. При заполнении текстовой матрицы нужно учитывать, что размер матрицы может превосходить длину строки и тогда будет обращение к защищённой памяти и останов программы по ошибке (не "вылет"). Тут можно сделать так
for i := 0 to r - 1 do for j := 0 to b - 1 do begin //OutPutDebugString(PWideChar(inttostr(i)+' '+inttostr(j))); if i * b + j + 1 <= Length(Text) then Textmatr[key1[i] - 1, j] := Text[(i) * b + j + 1] else Textmatr[key1[i] - 1, j] := ' '; end;
Добавлено через 8 мин. После этих исправлений получаю
Код
введите кол-во строк в матрице : 6 введите кол-во столбцов в матрице : 4 введите текст для кодировки: ШИФРОВАНИЕ_ПЕРЕСТАНОВКОЙ Введите ключ 1 , состоящий из 6 символов, через "Enter" 5 3 1 2 4 6 Введите ключ 2, состоящий из 4 символов, через "Enter" 4 2 3 1
k1\k2 0 И Е _ П 1 Е Р Е С 2 О В А Н 3 Т А Н О 4 Ш И Ф Р 5 В К О Й Закодированный текст: ПСНОРЙЕРВАИК_ЕАНФОИЕОТШВ Раскодированный текст: ИШИФИОВАИИЕ_ИЕРЕИТАНИВКО
Т.е. обратное преобразование неправильное. Но сначала добейтесь правильного шифрования, а потом будем продолжать.
Автор: Cherry225 22.10.2016 3:53
Спасибо большое, программа заработала
Автор: Федосеев Павел 22.10.2016 10:29
Всё заработало (и кодирование и декодирование)?
Вы пользуетесь автоформаттером исходного кода?
Автор: Cherry225 22.10.2016 10:56
Да, заработала и шифровка и дешифровка. И да, пользуюсь)