Avatar billede jonat Nybegynder
11. oktober 2005 - 23:15 Der er 19 kommentarer og
1 løsning

Power(123,17) mod 3233 problem

Hey... Sidder med et matematikproblem i delphi.

Har et tal 123 som skal opløftes i 17.
Det kan delphi også fint nok, og jeg får et tal som hedder 3,xxxE35.
Meget stort tal.
Der efter skal "mod" 3233 tages at det store tal.

Det kan den bare ikke, den siger:
"Operator not applicable to this operand type"

Hvordan kommer jeg udenom det?

Det jeg bruger:
procedure TForm1.Button1Click(Sender: TObject);
var
  Encrypt, Decrypt, PQ : Real48;
Const
  P = 61;
  Q = 53;
  N = 3233;
  E = 17;
  D = 2753;
  Start = 123;
begin
  Encrypt := (Power(123,17)) mod N;
  ShowMessage(FloatToStr(Encrypt));
end;

Ps. Det er til en krypteringsalgorithme jf: http://en.wikipedia.org/wiki/Modular_arithmetic
og
http://ga.randers-hf-vuc.dk/matlex/kode.html nederst.

Det er RSA kryptering

Håber i kan hjælpe mig med at komme videre :)

På forhånd Tak, Jonatan
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:16 #1
Power(123,17) giver en floating point og sådan en kan du ikke tage mod på

du skal have fat på en "big integer" pakke
11. oktober 2005 - 23:27 #2
Du må jo nok kunne lave det på en anden måde.

StortTal := Power(123,17);
Encrypt  := StortTal - (Round(StortTal / N) * N);

Du tager StortTal dividerer med N, afrunder til nul decimaler og ganger med N igen.
Forskellen mellem dette facit og det oprindelige tal må vel være modulus.
Avatar billede jonat Nybegynder
11. oktober 2005 - 23:37 #3
Med den her kode:
procedure TForm1.Button1Click(Sender: TObject);
var
  Encrypt, StortTal, Decrypt, PQ : Real48;
Const
  P = 61;
  Q = 53;
  N = 3233;
  E = 17;
  D = 2753;
  Start = 123;
begin
  StortTal := Power(123,17);
  Encrypt  := StortTal - (Round(StortTal / N) * N);
  ShowMessage(FloatToStr(Encrypt));
end;

Får jeg en fejl som hedder: "EInvalidOp" og i programmet fortæller den: "Invalid Floating Point Operation"

// Jonatan
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:40 #4
nej - fordi en floating point har ikke bits nok til at repræsentere de heltal
Avatar billede jonat Nybegynder
11. oktober 2005 - 23:40 #5
Pga. de er så store?
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:42 #6
ja

3,xxxE35 er 3,xxxE35 +/- rigtigt mange milliarder d.v.s. at modulus giver ingen mening
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:42 #7
derfor skal du have fat på en big integer pakke
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:43 #8
jeg lavede engang den her kode:

program BigInt;

{$APPTYPE CONSOLE}

uses
  SysUtils;

function numval(c : char) : integer;

begin
  numval := ord(c) - ord('0');
end;

function strval(v : integer) : char;

begin
  strval := chr(ord('0') + v);
end;

function add(v1,v2 : string) : string;

var
  res : string;
  ix1, ix2, tmp, carry : integer;

begin
  res := '';
  carry := 0;
  ix1 := length(v1);
  ix2 := length(v2);
  while (carry > 0) or (ix1 > 0) or (ix2 > 0) do begin
      tmp := carry;
      if(ix1 > 0) then begin
          tmp := tmp + numval(v1[ix1]);
          ix1 := ix1 - 1;
      end;
      if(ix2 > 0) then begin
          tmp := tmp + numval(v2[ix2]);
          ix2 := ix2 - 1;
      end;
      res := strval(tmp mod 10) + res;
      carry := tmp div 10;
  end;
  add := res;
end;

function mulpow10(v : string; pow10 : integer) : string;

var
  res : string;
  i : integer;

begin
  res := v;
  for i := 1 to pow10 do begin
      res := res + '0';
  end;
  mulpow10 := res;
end;

function mulone(v : string; num : integer) : string;

var
  res : string;
  ix, tmp, carry : integer;

begin
  res := '';
  carry := 0;
  ix := length(v);
  while (carry > 0) or (ix > 0) do begin
      tmp := carry;
      if(ix > 0) then begin
          tmp := tmp + num * numval(v[ix]);
          ix := ix - 1;
      end;
      res := strval(tmp mod 10) + res;
      carry := tmp div 10;
  end;
  mulone := res;
end;

function mul(v1,v2 : string) : string;

var
  res : string;
  i : integer;

begin
  res := '0';
  for i := 1 to length(v2) do begin
      res := add(res,mulpow10(mulone(v1,numval(v2[i])),length(v2)-i));
  end;
  mul := res;
end;

var
  i : integer;
  fac : string;

begin
  (* functionality test *)
  writeln(add('1234','12345678'));
  writeln(mulpow10('123',2));
  writeln(mulone('123456',2));
  writeln(mul('12345','12345'));
  (* performance test *)
  fac := '1';
  for i := 1 to 500 do begin
    fac := mul(fac, inttostr(i));
    writeln(i,' ',fac);
  end;
end.
Avatar billede jonat Nybegynder
11. oktober 2005 - 23:43 #9
Og hvad er det, det er?
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:44 #10
men der findes meget meget meget meget bedre big integer pakker en det !
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:45 #11
Avatar billede jonat Nybegynder
11. oktober 2005 - 23:46 #12
Det er til rigtig store tal ik?

Kan du lave et eksempel på hvordan det kombineres med mit projekt, for facit giver et tal på 3 cifre

Ps. Spm: "Og hvad er det, det er?" var til hvad en Big integer pakke var :)
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:47 #13
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:48 #14
en big integer pakke er ent bibliotek som kan regne med vilkårligt store heltal
100 cifre, 1000 cifre, 10000 cifre
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:49 #15
og du kigger i pakken efter pow og mod og sålaver du bare

BigIntMod(BigIntPower(123,17),N)

eller hvad den nu hedder

at resultatet er 0..N-1 og dermed ret lille gør jo ikke at mellemregningerne ikke
kan blive store
Avatar billede jonat Nybegynder
11. oktober 2005 - 23:50 #16
Ok... Mange tak for hjælp...

Mine forældre siger at jeg skal i seng nu, så kikker lige videre på det imorgen...

Men tak for hjælpen til nu :D

// Jonatan
Avatar billede arne_v Ekspert
11. oktober 2005 - 23:51 #17
jeg ligger et svar just in case
Avatar billede jonat Nybegynder
12. oktober 2005 - 11:00 #18
Jeg har prøvet at kikke på den pakke der hedder: "LongInt" på http://www.efg2.com/Lab/Library/Delphi/MathFunctions/Cryptography.htm (nederst)...

Jeg kan bare ikke finde ud af hvordan jeg bruger den :S

// Jonat
Avatar billede lsc Nybegynder
12. oktober 2005 - 14:19 #19
Jeg er ikke sikker på at jeg har regnet rigtigt, men måden kan måske være at bruge logaritmer, så undgår man tit overflow.

Prøv for sjovt denne variation:


procedure TForm1.Button1Click(Sender: TObject);
var  Encrypt, StortTal, Decrypt, PQ, LogStorttal, Nl: extended;
Const
  P = 61;
  Q = 53;
  N = 3233.0;
  E = 17;
  D = 2753;
  Start = 123;
begin
  StortTal := Power(123,17);
  LogStorttal := ln(storttal);
  Nl := ln(N);
  encrypt := exp((Round(logStortTal / Nl) - Nl));
  ShowMessage(FloatToStr(Encrypt));
end;
Avatar billede jonat Nybegynder
12. oktober 2005 - 15:59 #20
Hej arne_v...

Har nu arbejdet på det, og har fundet en løsning med denne Dll, http://www.delphiforfun.org/Programs/Library/big_integers.htm ... og det virker :)

Mange tak, du får Point...

lsc, din løsning gav 6,xxx og den skal give 855, og det gør arne_v's link.

Min løsning:
implementation

{$R *.dfm}     
uses UBigIntsV2, math;

procedure TForm1.Button1Click(Sender: TObject);
var g,e,m :Tinteger;
begin
g:=TInteger.create;
e:=TInteger.create;
m:=TInteger.create;
g.assign(IntToStr(Start));
e.assign('17');
m.assign(IntToStr(N));
g.modpow(e,m);
ShowMessage(g.ConvertToDecimalString(true));
g.free;
e.free;
m.free;

// Jonat.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester