Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Алгоритм RSA на perl


Автор: rainz 17.9.2011, 13:14
Решил написать, чисто из спортивного интереса.. но что то идет не так, в генерации открытого ключа.. может кто поможет?

Код

#!/usr/bin/perl -w

use strict;
use v5.10;

my $cryptStr = $ARGV[0];
my %alphabet = ("a"=>1,  "b"=>2,  "c"=>3,  "d"=>4, 
                "e"=>5,  "f"=>6,  "g"=>7,  "h"=>8, 
                "i"=>9,  "j"=>10, "k"=>11, "l"=>12, 
                "m"=>13, "n"=>14, "o"=>15, "p"=>16,
                "q"=>17, "r"=>18, "s"=>19, "t"=>20,
                "u"=>21, "v"=>22, "w"=>23, "x"=>24, 
                "y"=>25, "z"=>26, "."=>27, ","=>28,
                " "=>29);
                
#весь текст в нижний регистр, и разбиваем по буквам
$cryptStr = lc($cryptStr);
my @charsStr = unpack("A1" x length($cryptStr), $cryptStr);

#объявляем все нужные ключи и переменные..
my $FirstNumb  = int(rand 50);
my $SecondNumb = int(rand 50);
my $Modul = $FirstNumb*$SecondNumb;
my $PhiFromN = ($FirstNumb-1)*($SecondNumb-1);
my $OpenKey = int(rand 50);
my $SecretKey = &genSecretKey;
my $cryptText = "";

#подбор подходящего ключа
while (!(&relprime($OpenKey, $PhiFromN))) {
    $OpenKey += 2;
}

#проверка на взаимную простоту
sub relprime {
    my $a = $_[0];
    my $b = $_[1];
    while(($a!=0) && ($b!=0)) {
        if ($a>=$b){$a=$a%$b;} 
        else {$b=$b%$a;}    
    }
    if (($a+$b)==1){ return 1;}
    else {return 0;}
}

#алгоритм Эвклида для генерация ключа дешифрования
sub genSecretKey {
    my $u1 = 1;
    my $u2 = 0;
    my $u3 = $PhiFromN;
    my $r1 = 0;
    my $r2 = 1;
    my $r3 = $OpenKey;
    
    while ($r3)
    {
        if(!$r3) {break;}
        
        my $q = int($u3/$r3);
        my $t1 = ($u1-$r1*$q);
        my $t2 = ($u2-$r2*$q);
        my $t3 = ($u3-$r3*$q);
        $u1=$r1;
        $u2=$r2;
        $u3=$r3;
        $r1=$t1;
        $r2=$t2;
        $r3=$t3;
    }
    return $u2;
}


#шифруем текст посимвольно
foreach my $letter (@charsStr){
    my $textForCrypt = $alphabet{$letter};
    $cryptText .= ($textForCrypt**$OpenKey) % $Modul . " ";
}
print "" . $cryptText . "\n";

#меняем в алфавите ключи на значения
my @alphabet_keys = keys %alphabet;
my @alphabet_values = values %alphabet;
%alphabet = ();
@alphabet{@alphabet_values} = @alphabet_keys;

#разбиваем шифрованный текст посимвольно
my $originText = "";
my @cryptText = split(/ /, $cryptText);

#расшифровываем текст по одному символу
foreach my $cryptcode (@cryptText) {
    my $codeOfChar = ($cryptcode**$SecretKey) % $Modul;
    $originText .= $alphabet{$codeOfChar};
}
print $originText . "\n";

Автор: Pfailed 17.9.2011, 15:44
Я делал такое когда учился в универе. Прикладываю свой вариант. Там программа с GUI на GTK2, хотя реализация алгоритма в отдельном модуле, только в модуле этом одна странность: он берет простые числа из базы. Можно это заменить на генерацию чисел с помощью Crypt::Primes, например.
Если нужно, могу порекомендовать книгу, где хорошо описаны эти алгоритмы.

Автор: dixoNICH 17.9.2011, 18:06
Порекомендуйте книгу, пожалста smile

Автор: Pfailed 17.9.2011, 18:13
dixoNICH, http://www.ozon.ru/context/detail/id/2439404/

Автор: gcc 17.9.2011, 22:37
http://www.q0.org.ua/photo/view/25/245

Автор: shamber 17.9.2011, 22:57
gcc, у мну аж весь экран заняло %)

Автор: rainz 17.9.2011, 23:26
Pfailed Огромное спасибо! А что по коду, может я что то где то неправильно закодил? так хотяб на вскидку? книгу скачал, читаю smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)