⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.pas

📁 Delphi实现的RSA算法源码
💻 PAS
字号:
{ (c) Joachim Mohr
 Hinweis: Die Prozeduren wurden von Turbo-Pascal 黚ernommen.
          Um 18-stellige Primzahlen darstellen zu k鰊nen, wurde statt
          longint der Typ extended genommen (in Delphi w鋜e int64 m鰃lich
          oder die Verwendung der Klasse Jedi.bigintegers).
          Gr鲞ere als 18-stellige Primzahlen sind ung黮tig!

          Hier d黵fen h鯿hstens 9-stellige Zahlen vorkommen, da
          quadriert wird!

          "n div m" ist bei extended dann int(n/m+g_eps).
          "n mod m" ist bei extended dann n-int(n/m+g_eps)*m. Siehe unten "mod_".

          Das "gobale Epsilon" g_eps=1E-15 ist n鰐ig, da extended ganze Zahlen
          nur angen鋒ert speichert, statt 13 z.B. 12.99999..9 und
          int(12.99999.9) ist verschieden von int(13)!
          Setzten Sie hier g_eps=0, dann werden falsche Ergebnisse geliefert!

          Ich habe auch schon bei manchen Compilern erlebt: int(0.1+0.9)=0
          [Eigentlich klar: 0.1= 0.00011001100110...(im Zweiersystem)
                            0.9= 0.11100110011001...(im Zweiersystem)
                   Also 0.1+0.9= 0.11111111111111...(im Zweiersystem)
                             int(0.irgenwas)=0
          Zur Erinnerung 0.11111111... (im Zweiersystem)=1/2+1/4+1/8+...=1]

Bug: Fehler bei Umlauten
}

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    B_v_e: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    Memo3: TMemo;
    B_v_d: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Button4: TButton;
    Label4: TLabel;
    E_n: TEdit;
    Label5: TLabel;
    B_close: TButton;
    B_Bsp: TButton;
    E_e: TEdit;
    E_d: TEdit;
    Label6: TLabel;
    Label7: TLabel;
    Label8: TLabel;
    procedure B_v_eClick(Sender: TObject);
    procedure B_v_dClick(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure B_closeClick(Sender: TObject);
    procedure B_BspClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

const
  B = 256; //Ascii mit Steuerzeichen
  BB = B * B; //Berechnet schon der Compiler
var
  Form1: TForm1;

implementation

uses
  jmhilf, jmMath, //wg g_eps
  Unit2;

{$R *.DFM}

//Mit extended k鰊nen mit Pascal gr鲞ere Primzahlen dargestellt werden.
//In Delphi k鰊nte man stattdessen auch mit int64 arbeiten.

function gerade_(const x: extended): boolean; //'_' wg. extended
begin
  result := (abs(x - int(x / 2 + g_eps) * 2) < g_eps);
end;

function mod_(const x, m: extended): Extended;
begin
  if (x >= 0) and (x < m - 0.5) then
    result := x
  else
    result := x - int(x / m + g_eps) * m
end;

{Ohne mod w鋜e h(x,n)=x^n rekursiv
function h(x:extended; n:integer):extended;
begin
  if n=0 then result:=1 else
    if odd(n) then result:=x*h(x,n-1) else
      result:=h(sqr(x),n div 2)
end;}

{Iterativ: Achtung: da sqr vorkommt, ist Ergebnis nur f黵 h鯿hstens 9 Stellen g黮tig!}

function HOCH_MOD_(m, e: extended; const n: extended): extended; //m^e mod n
begin //z.B. 2^21  m=2 e=21
  result := 1;
  while true {abs(e)>g_eps} do
  begin
    if not gerade_(e) then
    begin
      //result:=result*m;             result=2   2      2^5    2^5    2^21
      result := mod_(result * m, n);
    end;
    if e < 1.5 then exit; {d.h. e=1}
    //m:=sqr(m);                    //m=2^2      2^4    2^8    2^16   2^32
    m := mod_(sqr(m), n);
    e := int(e / 2 + g_eps); //e=10       5       2     1      0
  end;
end;

function f(const x, e, n: extended): extended;
  //      der RSA-Algorithmus x->x^e mod n
begin
  result := hoch_mod_(x, e, n); //=x^e mod n
end;

function VerschlZweierBlock(const c1, c2: char; const n, e: extended): extended;
   //(c1,c2)->y=ord(c1)+ord(c2)*B bijektiv von (Z/256*Z/256) -> Z/B^2
   //y->f(y) Z/B^2 -> Z/n nur injektiv. Deshalb keine Darstellung als Char*Char
begin
  result := f(ord(c1) + ord(c2) * B, e, n); //=(..)^e mod n
end;

function VerschlString(const s: string; const n, e: extended): string;
var
  k: integer;
  y: extended;
begin //Zweierbl鯿ke werden verschl黶selt
  result := '';
  for k := 1 to length(s) div 2 do
  begin
    y := VerschlZweierBlock(s[2 * k - 1], s[2 * k], n, e); //F黵 k=1 s[1],s[2], f黵 k=2 s[3],s[4], ...
    result := result + ssd(y, 0) + #13#10;
  end;
  //Evtl. das letzte Zeichen und ' '
  if length(s) mod 2 = 1 then
    result := result + ssd(VerschlZweierBlock(s[length(s)], ' ', n, e), 0);
end;

procedure VerschlMemoStrToDez(const n, e: extended);
begin
  form1.memo2.text := verschlString(form1.memo1.text, n, e);
end;

//Umkehrfunktion zu VerschlMemoStrToDez

procedure VerschlMemoDezToStr(const n, d: extended);
var
  i: integer;
  x, y: extended;
begin
  with Form1 do
  begin
    memo3.text := '';
    for i := 0 to memo2.Lines.Count - 1 do
    begin
      x := rr(memo2.lines[i]);
      y := f(x, d, n); //=x^e mod n
      memo3.text := memo3.text + char(round(mod_(y, B))) + char(trunc(y / B + g_eps));
    end;
  end;
end;

function lies_n(e: Tedit): extended;
begin
  try
    result := rr(e.text); //rr=StrtoFloat, tolerant
  except
    showmessage('Bitte geben sie f黵 n eine Zahl ein');
    result := 0;
    exit;
  end;
end;

procedure TForm1.B_v_eClick(Sender: TObject);
var
  n, e: extended;
begin
  n := lies_n(e_n);
  e := lies_n(e_e);
  VerschlMemoStrToDez(n, e);
  memo3.lines.clear;
end;

procedure TForm1.B_v_dClick(Sender: TObject);
var
  n, d: extended;
begin
  n := lies_n(e_n);
  d := lies_n(e_d);
  VerschlMemoDezToStr(n, d);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  close;
end;

procedure TForm1.B_closeClick(Sender: TObject);
begin
  close
end;

procedure TForm1.B_BspClick(Sender: TObject);
   //Text in String und zur點k siehe TTW Men

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -