Новости           

Программы

Turbo Pascal

Игры

Документация

"Странности"

FAQ

Ссылки

Благодарности

Гостевая книга

От автора

ШИФРЫ ЗАМЕНЫ

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

              abcdefghijklmnopqrstuvwxyz

         превращается в

              defghijklmnopqrstuvwxyzabc

              Отметим, что буквы abc выдвинулись и добавились в конец. Для
         того,  чтобы закодировать сообщение,  используя данный метод,  вы
         просто  подставляете  символы сдвинутого алфавита вместо реальных
         символов. Например, сообщение

              meet me at sunset

         превращается в

              phhw ph dw vxqvhw

              Программа, показанная  далее,  позволяет  зашифровать  любое
         текстовое сообщение, используя любое по вашему выбору смещение:

              { шифр простой замены }
              program subst;
              type
                str80 = string[80];

              var
                inf, outf: str80;
                start: integer;
                ch: char;

              procedure code (inf, outf: str80; start: integer);
              var
                infile, outfile: file of char;
                ch: char;
                t: integer;

              begin
                assign(infile, inf);
                reset(infile);
                assign(outfile, outf);
                rewrite(outfile);

                while not eof(infile) do
                begin
                  Read(infile, ch);
                  ch : = upcase(ch);
                  if (ch>='A') and (ch<='Z') then
                  begin
                    t  := ord(ch)+start;
                    if t>ord('Z') then t  := t-26;
                    ch  := chr(t);
                  end;
                  Write(outfile, ch);
                end;
                WriteLn('файл закодирован');
                close(infile); close(outfile);
              end;

              procedure decode(inf, outf: str80; start: integer);
              var
                 infile, outfile: file of char;
                 ch: char;
                 t: integer;

              begin
                assign(infile, inf);
                reset(infile);
                assign(outfile, outf);
                rewrite(outfile);

                while not eof(infile) do
                begin
                  read(infile, ch);
                  ch  := upcase(ch);
                  if (ch>='A') and (ch<='Z') then
                  begin
                    t  := ord(ch)-start;
                    if t

         в произвольную строку,  которая содержит все буквы алфавита, нап-
         ример

              qazwsxedcrfvtgbyhnujm ikolp

              Вы можете пожелать узнать,  значительно ли улучшается  стой-
         кость шифрования при использовании перемешанного варианта алфави-
         та по сравнению с вариантом простого смещения.  Ответ: да. Дело в
         том, что существует 26! вариантов перестановок алфавита, а с про-
         белом число вариантов достигает 27!. Факториал числа представляет
         собой произведение всех чисел,  не превосходящих данного.  Напри-
         мер,  6!  равно 6х5х4х3х2х1, то есть 720. Следовательно 26! очень
         большое число.

              Программа, представленная  далее,  реализует улучшенный шифр
         замены,  использующий перемешанный алфавит, показанный выше. Если
         вы закодируете сообщение

              meet me at sunset

         используя программу  реализации  улучшенного шифра замены,  полу-
         чится строка

              tssjptspqjpumgusj

         которую значительно труднее дешифровать.

              { улучшенный  шифр замены,  который использует перемешанный
               алфавит
              }
              program subs1;
              type
                str80 = string[80];

              var
                inf, outf: str80;
                alphabet,sub: str80;
                ch: char;

              { данная функция возвращает индекс в алфавите замены }
              function find(alphabet: str80; ch: char): integer;
              var
                t: integer;

              begin
                find  := -1; { код ошибки }
                for t := 1 to 27 do if ch=alphabet[t] then find  := t;
              end;   {find}

              {данная функция возвращает TRUE истина,
               если с - это буква алфавита }
              function isalpha(ch: char): boolean;
              begin
                   isalpha:=(upcase(ch)>='A') and (upcase(ch)<='Z');
              end;   {isalpha}

              procedure code(inf, outf: str80);
              var
                infile, outfile: file of char;
                ch: char;

              begin
                assign(infile, inf);
                reset(infile);
                assign(outfile, outf);
                rewrite(outfile);

                while not eof(infile) do
                begin
                  Read(infile, ch);
                  ch:=upcase(ch);
                if isalpha(ch) or (ch=' ') then
                  begin
                    ch:=sub[find(alphabet, ch)]; { найти замену }
                  end;
                  Write(outfile, ch);
                end;
                WriteLn('файл закодирован');
                close(infile); close(outfile);
              end;   {code}

              procedure decode(inf, outf: str80);
              var
                infile, outfile: file of char;
                ch: char;

              begin
                assign(infile, inf);
                reset(infile);
                assign(outfile, outf);
                rewrite(outfile);

                while not eof(infile) do
                begin
                  Read(infile, ch);
                  ch:=upcase(ch);
                  if isalpha(ch) or (ch=' ') then
                  ch:=alphabet[find(sub,ch)]; {замена снова на реальный
                                                    алфавит }
                  Write(outfile, ch);
                end;
                WriteLn('файл декодирован');
                close(infile); close(outfile);
              end;   {decode}


              begin
                alphabet  := 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ';
                sub       := 'CAZWSXEDCRFVTGBYHNUJM IKOLP';
                Write('введите имя входного файла : ');
                ReadLn(inf);
                Write('введите имя выходного файла : ');
                ReadLn(outf);
                Write('кодировать или декодировать  (C or D): ');
                ReadLn(ch);
                if upcase(ch)='C' then code(inf, outf)
                else if upcase(ch)='D' then decode(inf, outf);
              end.
              Хотя дешифрация рассматривается далее в этой главе, вам сле-
         дует знать, что даже такой улучшенный код замены может быть срав-
         нительно легко дешифрован, используя частотные таблицы английско-
         го языка, в которых дана статистическая информация по использова-
         нию каждой буквы алфавита. Как вы можете легко заметить, глядя на
         зашифрованное сообщение, "s" почти наверняка является буквой "е",
         наиболее часто встречающейся буквой английского алфавита, а "р" -
         пробелом. Оставшаяся часть сообщения может быть дешифрована быст-
         ро и легко.

              Чем больше шифрованное сообщение, тем легче расшифровать его
         с помощью частотных таблиц.  Для того,  чтобы осложнить успех де-
         шифровальщика,  применяющего частотные таблицы, вы можете исполь-
         зовать шифр множественной замены.  Одна и та же буква в  исходном
         сообщении  не обязательно преобразуется в одну букву шифрованного
         текста.  Один из возможных методов реализации шифра множественной
         замены  состоит в добавлении второго перемешанного алфавита и пе-
         реключении с одного алфавита на другой при встрече в тексте  про-
         бела. Пусть вторым перемешанным алфавитом будет следующий:

              poi uytrewqasdfghjklmnbvcxz

              Тогда, используя данный подход, сообщение

              meet me at sunset

         будет зашифровано в вид

              tssj su qj kmdkul

              Чтобы понаблюдать, как это выполняется, запишите упорядочен-
         ный алфавит и два перемешанных алфавита один под другим,  как по-
         казано ниже

              алфавит: abcdefghijklmnopqrstuvwxyz<пробел>
              замена:  qazwsxedcrfvtgbyhnujm ikolp
              замена2: poi uytrewqasdfghjklmnbvcxz

              В начале  работы программы используется первый алфавит.  Это
         означает,  что "meet" кодируется в "tssj". Когда встречается пер-
         вый пробел происходит переключение на второй алфавит,  приводящее
         к кодированию слова "me"  в  "su".  Следующий  пробел  заставляет
         программу использовать снова первый алфавит. Этот процесс продол-
         жается до тех пор, пока не будет закодировано все сообщение.

              Данная программа создает шифр множественной замены:
              { шифр множественной замены }
              program subs3;
              type
                str80=string[80];

              var
                inf, outf: str80;
                alphabet, sub, sub2: str80;
                ch: char;

              {данная функция  возвращает
               индекс в  алфавите подстановки }
              function find(alphabet: str80; ch: char): integer;
              var
                t: integer;

              begin
                find:= -1;  { код ошибки }
                for t:= 1 to 27 do if ch=alphabet[t] then find:= t;
              end;  {find}

              {This function returns TRUE if ch is a letter
               of the alphabet.}
              function isalpha(ch: char): boolean;
              begin
                isalpha:= (upcase(ch)>='A') and (upcase(ch)<='Z');
              end;  {is alpha}

              procedure code(inf, outf: str80);
              var
                infile, outfile: file of char;
                ch: char;
                change: boolean;

              begin
                assign(infile, inf);
                reset(infile);
                assign(outfile, outf);
                rewrite(outfile);

              change  := TRUE;
              while not eof(infile) do
              begin
                Read(infile,ch);
                ch := upcase(ch);

                { переключение алфавитов при каждом пробеле }

                if ch=' ' then change  := not change;
                if isalpha(ch) then
                begin
                  if change then
                   ch:=sub[find(alphabet,ch)]
                  else
                   ch:=sub2[find(alphabet,ch)];
                end;
                Write(outfile, ch);
              end;
                WriteLn('файл закодирован ');
                close(infile); close(outfile);
              end;  {code}

              procedure decode(inf, outf: str80);
              var
                infile, outfile: file of char;
                ch: char;
                change: boolean;

              begin
                assign(infile, inf);
                reset(infile);
                assign(outfile, outf);
                rewrite(outfile);

                change  := TRUE;
                while not eof(infile) do
                begin
                  Read(infile, ch);
                  ch  := upcase(ch);
                  if ch=' ' then change  := not change;
                  if isalpha(ch) then
                  begin
                    if change then
                      ch:=alphabet[find(sub, ch)] {find substitution}
                    else
                      ch:=alphabet[find(sub2, ch)]; {second sub}
                  end;
                  Write(outfile, ch);
                end;
                WriteLn('файл декодирован ');
                close(infile); close(outfile);
              end;

              begin
                alphabet:='ABCDEFGHIJKLMNOPQRSTUVWXYZ ';
                sub     :='QAZWSXEDCRFVTGBYHNUJM IKOLP'; {алфавит #1}
                sub2    :='POI UYTREWQASDFGHJKLMNBVCXZ'; {алфавит #2}

                Write('введите имя входного файла : ');
                ReadLn(inf);
                Write('введите имя выходного файла : ');
                ReadLn(outf);
                Write('кодировать или декодировать (C or D): ');
                ReadLn(ch);
                if upcase(ch)='C' then code(inf, outf)
                else if upcase(ch)='D' then decode(inf, outf);
              end.


              Использование шифров множественной замены  существенно  зат-
         рудняет дешифрацию кода с применением частотных таблиц,  изза то-
         го, что разные буквы в разные моменты времени отображаются в одни
         и те же символы. Если вы поразмыслите над этой проблемой, то най-
         дете, наверное, методы использования различных перемешанных алфа-
         витов  и  более сложные процедуры переключения их,  которые дадут
         одинаковую частоту использования букв в зашифрованном  тексте.  В
         этом  случае частотные таблицы окажутся бесполезными при дешифра-
         ции кода.
Б.зкуЮ



(с)Все права защищены

По всем интересующим вопросампрошу писать на электронный адрес

    Rambler's Top100 PROext: Top 1000
    Rambler's Top100 Яндекс цитирования
Hosted by uCoz