![]() |
|
|
#1
|
|||
|
|||
|
зашифровать текст методом цезаря. алфавит-английские строчные буквы, сдвиг +3, и еще нужно ключ вводить с клавы.
вот что у меня получилось , но странно работает, точней шифрует нормально только первую букву. Подскажите что не так Код:
var
Form1: TForm1;
slovo,kluch,shifr,rasslovo:string;
sl,kl,sh,rassl:char;
i,k:integer;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
shifr:='';
slovo:=edit1.Text;
kluch:=edit2.Text;
for i:=1 to length(slovo) do
begin
sl:=slovo[i];
kl:=kluch[i];
sh:=chr(100+(ord(sl)-97+ord(kl)-97)mod(26));
shifr:=shifr+sh;
end;
edit3.Text:=shifr;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
close;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
rasslovo:='';
shifr:=edit3.text;
kluch:=edit2.Text;
for k:=1 to length(shifr) do
begin
sh:=shifr[k];
kl:=kluch[k];
rassl:=chr(94+(ord(sh)-97+ord(kl)-97)mod(26));
rasslovo:=rasslovo+rassl;
end;
edit4.Text:=rasslovo;
end; |
|
#2
|
||||
|
||||
|
Дельфяка рядом нет, так что на глаз меня смущают разницы в строках
Код:
sh:=chr(100+(ord(sl)-97+ord(kl)-97)mod(26)); ... rassl:=chr(94+(ord(sh)-97+ord(kl)-97)mod(26)); Это раз. Во-вторых в цезаре при расшифровке вычитание, у тебя опять сложение. В-третьих написал бы строку разрешённых символов и работал бы с ней, как с алфавитом (чем не кольцо?), меньше бы проблем имел ![]() Последний раз редактировалось Ferra, 02.06.2010 в 05:03. |
|
#3
|
|||
|
|||
|
то есть задать строка символов вот так задать
const a:string=('abcdefghijklmnopqrstuvwxyz') или const Buk:array[0..25] of char=('a','b','c','d','e','f','g','h','i','j','k', 'l','m','n','o','p','q','r','s','t','u','v','w','x ','y','z') var b:array[0..25] of char; а где там нужно поменять знаки? а мне казалось что все логично вроде) sh:=chr(100+(ord(sl)-97+ord(kl)-97)mod(26)); ... rassl:=chr(94+(ord(sh)-97+ord(kl)-97)mod(26)); а так в целом нормально, чтоб зашифровать с ключом(кодовое слово) и со сдвигом на какое-то число? |
|
#4
|
||||
|
||||
|
Меня смущает то, что ты складываешь i-й символ ключа с i-м текста в обоих случаях. Во-вторых в Шифре Цезаря идёт сдвиг каждого символа на определённое фиксированное число. Так что поясни что ты хочешь сделать.
http://ru.wikipedia.org/wiki/Шифр_Цезаря Сча набросал, вроде работает, лови: Код:
//Найти позицию символа в алфавите
function PosInVoc(Symbol : Char; Vocabulary : String) : Word;
var
i : Word;
begin
Result := 0;
for i := 1 to Length(Vocabulary) do
if Vocabulary[i] = Symbol then
begin
Result := i;
break;
end;
end;
//Шифрование Цзарем
function Caesar(Text : String; Seed : Byte; Vocabulary : String; Encrypt : Boolean = True) : String;
var
i : LongWord;
n, pos : Word;
begin
Result := '';
n := Length(Vocabulary);
Seed := Seed mod n;
if Length(Text) <> 0 then
for i := 1 to Length(Text) do
begin
pos := PosInVoc(Text[i], Vocabulary);
if Encrypt then Result := Result + Vocabulary[(pos + Seed) mod n]
else Result := Result + Vocabulary[(pos - Seed + n) mod n]
end;
end;
//Использование
procedure TForm1.Button1Click(Sender: TObject);
Begin
//текст - "hello", шифруется в эдит1, дешифрация в эдит2
Edit1.Text := Caesar('hello', 3, 'qwertyuiopasdfghjklzxcvbnm', true);
Edit2.Text := Caesar(Edit1.Text, 3, 'qwertyuiopasdfghjklzxcvbnm', false);
end; |
|
#5
|
|||
|
|||
|
да , в вики он дан как просто шифр со сдвигом , но надо еще ключ замостить , к примеру , "yes" и тогда получиться такое соответствие
a b c d e f g h i j k l m n o p q r s t u v w x y z w x z y e s a b с d f g h i j k l m n o p q r t u v в твоей проге мы в коде указываем текст котрый потом зашифруеться , но нужно его вводить вручную, я как бы указал это , изменив код , но в итоге происходит только сдвиг букв Edit1.Text := Caesar(edit4.text, 3, 'abcdefghijklmnopqrstuvwxyz', true); Edit3.Text := Caesar(Edit1.Text, 3, 'abcdefghijklmnopqrstuvwxyz', false); |
|
#6
|
||||
|
||||
|
http://ru.wikipedia.org/wiki/Полиалфавитный_шифр
http://articles.org.ru/cn/showdetail.php?cid=8341 Вообще если сдвигать по ключу, то это Не Цезарь, а шифр Вижинера. Вот код: Код:
function PosInVoc(Symbol : Char; Vocabulary : String) : Word;
var
i : Word;
begin
Result := 0;
for i := 1 to Length(Vocabulary) do
if Vocabulary[i] = Symbol then
begin
Result := i;
break;
end;
end;
function Viginer(Text : String; Key : String; Vocabulary : String; Encrypt : Boolean = True) : String;
var
i, k : LongWord;
n, pos, posk : Word;
begin
Result := '';
n := Length(Vocabulary);
k := 1;
if Length(Text) <> 0 then
for i := 1 to Length(Text) do
begin
pos := PosInVoc(Text[i], Vocabulary);
posk := PosInVoc(Key[k], Vocabulary);
if pos = 0 then break;
if Encrypt then Result := Result + Vocabulary[(pos + posk) mod n]
else Result := Result + Vocabulary[(pos - posk + n) mod n];
if k > Length(Key) then k := 1
else inc(k);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
Begin
Edit1.Text := Viginer(EditText.Text, EditKey.Text, 'abcdefghigklmnopqrstuvwxyz', true);
Edit2.Text := Viginer(Edit1.Text, EditKey.Text , 'abcdefghigklmnopqrstuvwxyz', false);
end;
|
|
#7
|
|||
|
|||
|
а сейчас не хочет запускаться , ошибка - EditText.text не понимает , наверно опечатка , но когда исправляю вот так ,
Edit1.Text := Viginer(Edit3.Text, EditKey.Text , 'abcdefghigklmnopqrstuvwxyz', true); Edit2.Text := Viginer(Edit1.Text, EditKey.Text , 'abcdefghigklmnopqrstuvwxyz', false); то начинает не понимать что такое EditKey и увидел ошибку после then (comparing signed and unsigned types - widened both operands) if k > Length(Key) then k := 1 else inc(k); |
|
#8
|
||||
|
||||
|
Лови, так будет проще, чем объяснять основы. Delphi 7.
|
|
#9
|
|||
|
|||
|
разберусь , благодарю за помощь)
|
|
#10
|
||||
|
||||
|
Эта проверка на то, есть ли текущий символ текста в алфавите:
Код:
if pos = 0 then break; |
|
#11
|
|||
|
|||
|
а function Viginer делфи знает как стандартную или мы просто так ее обозвали? извиняюсь за глупый вопрос, но чтоб уж точно понять)
|
|
#12
|
||||
|
||||
|
Мы дали ей такое название, её можно было назвать как угодно и потом вызывать по этому имени.
http://informatics.lgg.ru/pascal9.html Почитай - там доступно рассказано, по сути в Дельфи то же самое. |