📄 unit1.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 + -