Autor Beitrag
n3cRo
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mi 10.11.04 15:32 
Hi,
in der Schule machen wir gerade Kryptologie und ich bin mit nem Kumpel in die 2-Mann RSA-Gruppe gekommen, weil wir Mathe LK haben. Das mathematische an der Sache hab ich ja mittlerweile verstanden, aber die Delphi 5 Version und deren Problem mit langen Zahlen etc. macht mir doch zuschaffen :(
z.B. Krieg ich es nicht hin (33^17) mod 256 zu rechnen :(

Den Wert für e, N entnehm ich einem Editfeld - sie liegen dann als Integer vor, so auch der Ordinalwert der einzelnen, zu verschlüsselnden Buchstaben.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
unit mRSACodierer;

interface

uses sysutils, math, dialogs;

type
  RSACodierer = class

public
  { Public-Deklarationen }
  constructor init;
  function codiereText(pE: integer; pN: double; pText: string): string;
  function codiereZeichen(pZeichen: char): double;
  function decodiereText(pN, pD: integer; pCode: string): string;
  function decodiereZeichen(pZahl: string): double;
  destructor gibFrei;
private
  { Private-Deklarationen }
  zN, zD: double;
  zE: integer;
  function potenziere(pBasis: double; pExponent: integer): double;
  function potenziere_und_mod(pExponent: integer; pBasis, pDivisor: double): double;
  function mod_(pDividend, pDivisor: double): double;
end;

implementation

constructor RSACodierer.init;
begin

end;

function RSACodierer.codiereText(pE: integer; pN: double; pText: string): string;
var lCodierterText: string;
    i: integer;
begin
  zN := pN;
  zE := pE;
  lCodierterText := '';
  for i := 1 to length(pText) do
  begin
    lCodierterText := lCodierterText + FloatToStr(self.codiereZeichen(pText[i])) + ' ';
  end;
  result := lCodierterText;
end;

function RSACodierer.codiereZeichen(pZeichen: char): double;
var pZeichenOrd: integer;
begin
  pZeichenOrd := ord(pZeichen);
  result := potenziere_und_mod(zE, pZeichenOrd, zN);
end;

function RSACodierer.decodiereText(pN, pD: integer; pCode: string): string;
var lDecodierterText, lCodiertesZeichen: string;
    i: integer;
begin
  zN := pN;
  zD := pD;
  lDecodierterText := '';
  for i := 1 to length(pCode) do
  begin
    if pCode[i] <> ' ' then
      lCodiertesZeichen := lCodiertesZeichen + pCode[i]
    else
      begin
        lDecodierterText := lDecodierterText + chr(self.decodiereZeichen(lCodiertesZeichen));
        lCodiertesZeichen := '';
      end;
  end;
  result := lDecodierterText;
end;

function RSACodierer.decodiereZeichen(pZahl: string): double;
begin
  //result := hoch_und_mod(StrToFloat(pZahl), zD, zN);
  //result := StrToInt(FloatToStr((self.potenziere(StrToFloat(pZahl), zD)))) mod zN;
end;

destructor RSACodierer.gibFrei;
begin

end;

function RSACodierer.potenziere(pBasis: double; pExponent: integer): double;
begin
  //ShowMessage('Basis: ' + FloatToStr(pBasis) + ' - Expo: ' + IntToStr(pExponent));
    if pExponent = 0 then result := 1 else
      if odd(pExponent) then result := pBasis*self.potenziere(pBasis, pExponent-1)
        else result := self.potenziere(pBasis*pBasis, pExponent div 2)
end;

function RSACodierer.potenziere_und_mod(pExponent: integer; pBasis, pDivisor: double): double;
var lPotenz: double;
begin
  lPotenz := self.potenziere(pBasis, pExponent);
  result := self.mod_(lPotenz, pDivisor);
end;

function RSACodierer.mod_(pDividend, pDivisor: double): double;
var lNachKomma: double;
begin
  lNachKomma := pDividend/pDivisor - trunc(pDividend/pDivisor);
  result := round(lNachKomma*pDivisor);
end;

end.


Das decodieren ist noch fehlerhaft, basiert ja auch auf dem selben Schema ;)
Aber nur damit das Prinzip deutlich wird bzw. auf welchem Stand ich gerade bin hab ich mal den kompletten Code der Klasse hierhin kopiert.

Würd mich freuen wenn mir jemand sagen könnte wie ich das Problem lösen kann, kriege immer Fehler bei Gleitkommaoperation o.ä. und Integer ist als Typ zu klein für die Riesigenzahlen :(


Danke im Vorraus :)

Moderiert von user profile iconMotzi: Code- durch Delphi-Tags ersetzt.
MrSaint
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1033
Erhaltene Danke: 1

WinXP Pro SP2
Delphi 6 Prof.
BeitragVerfasst: Mi 10.11.04 16:13 
Hi!

hab mal für die schul nen RSA Chat geschrieben, der Keys bis zu 9 Byte verkraftet hat (also net wiklich sicher, aber mehr geht net mit den Delphi-Standardtypen) --> www.delphi-forum.de/viewtopic.php?t=16893
Also um das zu optimieren mit den Zahlen, benutz kein double, sondern nen int64 (du hast ja nur potenzen und modulos, also gibts keine kommazahlen, also kannst du in64 benutzen).. das is der größte standarddatentyp. Sollte dir das NICHT ausreichen, wirst du nicht drumrum kommen, eine Langzahlarithemtik zu schreiben. Das hab ich auch soweit schonmal angefangen gehabt, hat auch glab sogar soweit funktiniert, war aber schrecklich langsam und ich hab die nie mit RSA ausprobiert... Ne Langzahlarithmetik kann einfach mit beliebig langen Zahlen rechnen... Aber grad, wenn es für die schule is, dann wär mir persönlich das zu viel aufwand, da wird das mit den int64 schon reichen :)



MrSaint

_________________
"people knew how to write small, efficient programs [...], a skill that has subsequently been lost"
Andrew S. Tanenbaum - Modern Operating Systems
n3cRo Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Mi 10.11.04 17:10 
Danke danke, geht jetz und viel einfacher als die Ansätze die ich ergoogelt hab :)