Autor Beitrag
mtm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 64

Windows 10 Pro 64 Bit
Delphi XE 6
BeitragVerfasst: Fr 06.09.13 17:07 
Hallo zusammen,

ich habe im Netz zwar schon mal rumgeschaut aber irgendwie nichts passendes gefunden (vielleicht bin ich einfach zu dämlich). Ich möchte mit einer 24-stelligen ganzzahligen Zahl eine Modulo-Division durchführen.

Leider stoße ich dabei auf das Problem, daß die Zahl natürlich nicht in eine Integer-Variable passt und Modulo mit einem anderen Datentypen nicht funzt.

kurze Info : Ich bin dabei, mir testweise ein Programm zu schreiben, mit dem ich die IBAN von deutschen Konten berechnen kann.

Vielleicht hat da ja jemand von Euch eine Lösung

Danke im Voraus
mtm
FinnO
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1331
Erhaltene Danke: 123

Mac OSX, Arch
TypeScript (Webstorm), Kotlin, Clojure (IDEA), Golang (VSCode)
BeitragVerfasst: Fr 06.09.13 17:20 
Moin,

selbst bauen.

ausblenden Delphi-Quelltext
1:
2:
3:
4:
function mod(a,b : double) : double;
begin
  result := frac(a/b)*b; //nach belieben Runden. 
end;
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Fr 06.09.13 17:41 
Zu kurz gedacht :P
Double hat nur 16 Stellen, das Ergebnis wird also falsch sein.

Entweder mit strings arbeiten, einen vorhandenen Algo suchen oder etwas in Modulare Arithmetik einlesen ;-)

Ohne Gewähr, aber ich habe mal schnell geschaut:

(a*b + c) mod n = (a mod n) * (b mod n) + (c mod n)

Edit: Das Endergebnis natürlich wieder mod n. Die komplette, richtige Formel ist weiter unten.

Du kannst also deine 24 stellige Zahl in viele kleinere Abschnitte teilen (z.B. 4 Teile à 6 Ziffern) und dann hast du für b Terme wie 10^0, 10^6, 10^12 und 10^18. Die Ergebnisse von den vier (b mod n) Termen kannst du also vorher ausrechnen. Der Rest ist einfache Integer-Mathematik.


Zuletzt bearbeitet von jfheins am Sa 07.09.13 16:19, insgesamt 1-mal bearbeitet

Für diesen Beitrag haben gedankt: Martok
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Fr 06.09.13 17:52 
Hallo,
folgender Text testet die Korrektheit einer IBAN-Nummer:
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:
procedure CheckIBAN;
Var iban: string;
function ChangeAlpha(const input: string): string;
var
  a: Char;
begin
  Result := input;
  for a := 'A' to 'Z' do
  begin
    Result := StringReplace(Result, a, IntToStr(Ord(a) - 55), [rfReplaceAll]);
  end;
end;
function CalculateDigits(iban: string): Integer;
var
  v, l, rest, number: Integer;
  alpha: string;
begin
  iban := UpperCase(iban);
  if Pos('IBAN', iban) > 0 then 
    Delete(iban, Pos('IBAN', iban), 4);
  iban := iban + Copy(iban, 14);
  Delete(iban, 14);
  iban := ChangeAlpha(iban);
  v := 1;
  l := 9;
  rest := 0;
  alpha := '';
  try
    while v <= Length(iban) do
    begin
      if l > Length(iban) then l := Length(iban);
      alpha := alpha + Copy(iban, v, l);
      number := StrToInt(alpha);
      rest := number mod 97;
      v := v + l;
      alpha := IntToStr(rest);
      l := 9 - Length(alpha);
    end;
  except
    rest := 0;
  end;
  Result := rest;
end;
begin
  iban:=edit1.text;  //Eingabe
  iban := StringReplace(iban, ' ''', [rfReplaceAll]);
  if CalculateDigits(iban) = 1 then
    // korrekte IBAN
  else
    // IBAN fehlerhaft
end;

Der Quelltext muss einfach etwas umgebaut werden.

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
mandras
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 431
Erhaltene Danke: 107

Win 10
Delphi 6 Prof, Delphi 10.4 Prof
BeitragVerfasst: Fr 06.09.13 20:18 
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:

(a*b + c) mod n = (a mod n) * (b mod n) + (c mod n)


Definitiv nicht:
(a*b + c) mod n ist stets < n,
allein (a mod n) * (b mod n) kann schon bis zu (n-1)^2 werden
Marc.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1876
Erhaltene Danke: 129

Win 8.1, Xubuntu 15.10

BeitragVerfasst: Sa 07.09.13 14:54 
user profile iconmandras hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconjfheins hat folgendes geschrieben Zum zitierten Posting springen:

(a*b + c) mod n = (a mod n) * (b mod n) + (c mod n)

Definitiv nicht:
(a*b + c) mod n ist stets < n,
allein (a mod n) * (b mod n) kann schon bis zu (n-1)^2 werden

Stimmt! Er hat ein mod n vergessen: Wiki: Modulo Equivalencies.
Es ist nämlich nach korrekter Anwendung der Identäten und des Distributivgesetzes:
ausblenden Quelltext
1:
2:
(a*b + c) mod n = ((((a mod n)*(b mod n) mod n) mod n) + (c mod n)) mod n
                = (a mod n) * (b mod n) mod n + (c mod n)


Beste Grüße
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Sa 07.09.13 15:05 
Hallo,
user profile iconMarc. hat folgendes geschrieben Zum zitierten Posting springen:
Es ist nämlich nach korrekter Anwendung der Identäten und des Distributivgesetzes:
ausblenden Quelltext
1:
2:
(a*b + c) mod n = ((((a mod n)*(b mod n) mod n) mod n) + (c mod n)) mod n
                = (a mod n) * (b mod n) mod n + (c mod n)

Ist es auch nicht.
Für a=12, b=44, c=21, n=54 wird
ausblenden Quelltext
1:
2:
(a*b + c) mod n = 9 
(a mod n) * (b mod n) mod n + (c mod n) = 63

Richtig ist
ausblenden Quelltext
1:
(a*b + c) mod n = ((a mod n) * (b mod n) + (c mod n)) mod n					

was aber hier nicht viel bringt.

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
jfheins
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 918
Erhaltene Danke: 158

Win 10
VS 2013, VS2015
BeitragVerfasst: Sa 07.09.13 16:43 
Hi,
ja bei modularer Arithmetik muss man natürlich auch am Ende mod n rechnen. Habe oben einen entsprechenen Hinweis eingefügt.

Einen kleinen Einspuch bezüglich "was aber hier nicht viel bringt." möchte ich aber noch einbringen, weil die Formel ja durchaus das Problem löst. das Problem ist ja, von einer 24stelligen Zahl den modulao zu errechnen. Double genügt hierzu nicht.

Da oben schon IBAN angesprochen wurde, nehme ich mal die Zahl 141592653589793238462643 modulo 97:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
141592 653589 793238 462643 mod 97 =
(
(141592 * 10^18) mod 97 +
(653589 * 10^12) mod 97 +
(793238 * 10^6)  mod 97 +
462643 mod 97
) mod 97

Jetzt die Zehnerpotenzen 'rausziehen und berechnen (kann man später hart kodieren) ergibt:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
(
(141592 mod 97)*89 +
(653589 mod 97)*50 +
(793238 mod 97)*27 +
462643 mod 97)
) mod 97 = (69*89 + 3*50 + 69*27 + 50) mod 97 = 56

Das gleiche Ergebnis liefert mir WolframAlpha.
Die Rechnungen sind alle innerhalb des Integer-Wertebereichs machbar, oder sind sogar <2^16.

Wenn ich das richtig sehe, benutzt du ja im Grunde die gleiche Eigenschaft, nur steht die Formel bei dir nicht direkt im Code.
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Sa 07.09.13 21:05 
Hallo,

@user profile iconjfheins:
Zitat:
Da oben schon IBAN angesprochen wurde, nehme ich mal die Zahl 141592653589793238462643

Das riecht nach pi ohne die führende 3 :wink:
de.wikipedia.org/wik...100_Nachkommastellen

Gruß Horst