Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Mit einer kurzen Prozdur einen Schlüssel erzeugen (https://www.delphipraxis.net/20949-mit-einer-kurzen-prozdur-einen-schluessel-erzeugen.html)

kurtm1 25. Apr 2004 19:21


Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Hallo!
Es geht drum einen Schlüssel aus allen 26 Buchstaben des Alphabets zu erstellen, der aber keinen Buchstaben doppelt beinhaltet.

Gibt es da eine Funktion, oder eine kurze Prozedur?

Dies ist meine Lösung:

Code:
strSchluessel[1]:=chr(random(26)+65);
   for i:=2 to 26 do
   Begin
      j:=1;
      strBuchstabe:=chr(random(26)+65);
         repeat
           if strSchluessel[j]=strBuchstabe[1] then
           Begin
               strBuchstabe:=chr(random(26)+65);
               j:=0;
           end;
           j:=j+1;
         until j>i;
      strSchluessel[i]:=strBuchstabe[1];
   end;

gekmihesg 25. Apr 2004 19:34

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Delphi-Quellcode:
function createstr(count:integer); string;
var
 c: char;
begin
 result:='';
 if count > 26 then
  exit;
 while length(result) < count do
  begin
   c:=chr(random(26)+65);
   if pos(c,result) = 0 then
    result:=result + c;
  end;
end;

kurtm1 25. Apr 2004 19:40

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
danke, ist leider auch nicht viel kürzer. eine funktion scheint es ja nicht zu geben...

Nonsense 25. Apr 2004 19:41

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Näääädddd. Merke: Frage richtig lesen, dann posten. :mrgreen:

Dax 26. Apr 2004 12:25

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Delphi-Quellcode:
function Code: string;
var c: char;
begin
  randomize:
  while length(result) <= 26 do
  begin
    c := chr(random(26)+65);
    if pos(c, result) = 0 then result := result + c;
  end;
end;
Es dauert vielleciht ei wenig, bis ALLE 26 Buchstaben benutzt sind, aber dafür is sie schön kurz ;)

fiasko 26. Apr 2004 12:34

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Delphi-Quellcode:
function Code: string;
const
  s: string = 'abcdefghijklmnopqrstuvwxyz';
var
  i,j: Integer;
begin
  randomize;
  result:='';
  for i:=1 to 25 do
  begin
    j:=random(length(s)+1);
    result:=result+s[j];
    delete(s,j,1);
  end;
  result:=result+s;
end;
Ist vielleicht ein µ schneller...

Dax 26. Apr 2004 12:37

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Hat aber einen Fehler:

Gibt nur 25 Buchstaben aus.

Ansonsten eigentlich auch ein interessanter Ansatz.

fiasko 26. Apr 2004 12:39

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Zitat:

Zitat von Dax
1.) Gibt NUR 25 Buchstaben aus.

Hast du die Zeile result:=result+s; überlesen?

Zitat:

Zitat von Dax
2.) Niemand garantiert mir, das jeder nur ein mal vorkammt, du knallst einfach alles ins ergebnis, ohne zu checken, ob so was schon da ist...

Das delete haut doch die benutzten Wörte raus. Der Vorteil ist du brauchst keine Vergleichsoperationen mehr und schiebst nurnoch im Speicher rum...

Dax 26. Apr 2004 12:41

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Zitat:

Zitat von fiasko
Hast du die Zeile result:=result+s; überlesen?

Ja. :oops:

Zitat:

Zitat von fiasko
Das delete haut doch die benutzten Wörte raus. Der Vorteil ist du brauchst keine Vergleichsoperationen mehr und schiebst nurnoch im Speicher rum...

Hab' ich nachträglich rauseditiert, kuck mal nach :mrgreen:

fiasko 26. Apr 2004 12:43

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Zitat:

Zitat von Dax
Hab' ich nachträglich rauseditiert, kuck mal nach :mrgreen:

:shock:

Sharky 26. Apr 2004 12:45

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Oder so:

Delphi-Quellcode:
function TForm1.Button1Click(Sender: TObject) : String;
var
  myString1,
  myString2 : String;
  rand,
  ndx : Integer;
begin
  for ndx := 1 to 26 do
  begin
    myString1 := myString1+ Char(ndx+64);
  end;
  ndx := 0;
  While (Length (myString1) > 0) do
  begin
    rand := random(Length(myString1))+1;
    myString2 := myString2 + Copy (myString1,rand,1);
    Delete (myString1,rand,1)
  end;
  result := myString2;
end;
Ungetestet, darum auch nicht optimiert ;-)

fiasko 26. Apr 2004 12:48

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Der Ansatz kommt mir bekannt vor... 8)

Sharky 26. Apr 2004 12:51

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Zitat:

Zitat von fiasko
Der Ansatz kommt mir bekannt vor... 8)

:shock: Das kommt davon wenn man zwichen dem Tippen und dem Absenden ans Telefon muss :?

negaH 26. Apr 2004 13:03

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Delphi-Quellcode:
function Code: string;
const
  s: string = 'abcdefghijklmnopqrstuvwxyz';
var
  i,j: Integer;
begin
  randomize;
  result:='';
  for i:=1 to 25 do
  begin
    j:=random(length(s)+1);
    result:=result+s[j];
    delete(s,j,1);
  end;
  result:=result+s;
end;
der code ist ineffizient und zudem falsch. S ist eine Konstante die mit delete(s, j, 1) modifiziert wird. Beim nächsten Aufruf dieser Funktion wurde also S vorher schon modifiziert.
Ineffizient ist er weil er mit result := result + s[J], 26 realozierungen des Strings benötigt.
Randomize sollte auf nur EINMAL im Program aufgerufen werden.

Delphi-Quellcode:
function Code: String;
const
  Table: String = 'abcdefghijklmnopqrstuvwxyz';
var
  I,J: Integer;
  Temp: Char;
begin
  Result := Table;
  for I := 1 to Length(Table) do
  begin
    J := Random(Length(Table)) +1;
    Temp := Result[J];
    Result[J] := Result[I];
    Result[I] := Temp;
  end;
end;
Gruß Hagen

Sharky 26. Apr 2004 13:08

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Zitat:

Zitat von negaH
...Ineffizient ist er weil er mit result := result + s[J], 26 realozierungen des Strings benötigt....

Wusste ich doch das Hagen das mal irgendwo geschrieben hat. Darum verwende ich in einer Funktion immer temp_Variablen und setze Result ganz am ende der Funktion.

SirThornberry 26. Apr 2004 13:17

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Irgendwie versteh ich nicht wieso bei dem source jedes zeichen nur einmal vorkommt. Also ich zweifel is ni an (habs auch zig mal probiert) aber wie wird das sichergestellt? kannste den source mal erklären - irgendwie begreif ich den zu so früher stunde ni

Sharky 26. Apr 2004 13:27

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Zitat:

Zitat von SirThornberry
... kannste den source mal erklären ...

Wenn meinst Du denn?

SirThornberry 26. Apr 2004 13:28

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
eigentlich ist mir egal wer den source erklärt solange der source von Hagen (Negah) erklärt wird

Sharky 26. Apr 2004 13:34

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Wenn ich den Code richtig verstehe macht Hagen es so das er einmal den sortierten String hat.
Dann durchläuft er diesen von 1 bis 26 und ersetzt jedes Zeichen durch ein Zufällig ausgewähltes des gleichen Strings.

Grob gesagt: Er sorgt dafür das der Sring nicht mehr sortiert ist.

SirThornberry 26. Apr 2004 13:44

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
so weit bin ich auch mitgekommen. Aber wo/wie wird sichergestellt das, das zeichen nicht schon vorhanden ist...

The-X 26. Apr 2004 13:46

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
er würfelt nur die Reihenfolge der Zeichen in dem vorher sortierten String um,
somit ist kein Zeichen doppelt vorhanden, da nur z.B. die Position von a mit der von g getauscht wird

SirThornberry 26. Apr 2004 13:49

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
@The-X: Jetz wo dus sagst seh ichs auch. Man, auf sowas simples muss man erstmal kommen. Dadurch das ich irgendwie davon ausging das, der algo gleich arbeitet wie die vorhergehenden, hab ich das gar ni mitbekommen. Thx

negaH 26. Apr 2004 16:36

Re: Mit einer kurzen Prozdur einen Schlüssel erzeugen
 
Zitat:

Wusste ich doch das Hagen das mal irgendwo geschrieben hat. Darum verwende ich in einer Funktion immer temp_Variablen und setze Result ganz am ende der Funktion.
Das bezog sich damals auf was anderes.

Der obige Code ist deshalb effizienter weil er den 26 Zeichen umfassenden Speicherblock in Result nur EINMAL auf dem Heap alloziert.

Bei Result := Table; wird nur ein 4 Bytes Zeiger auf Table initialisiert. Table und Result zeigen in den gleichen Speicherbereich in dem "abcd...." stehen. Nun wird die Schleife ausgeführt. Innerhalb dieser Schleife erkennt der Compiler das Result geändert wird. Bevor er diese Änderung durchführt wird überprüft ob der Referenzzähler des gemeinsamen Strings 1 ist. Da er bei der ERSTEN Modifikation noch 2 ist wird nun auf dem Heap ein neuer Speicherbereich von 26 Zeichen alloziert und "abcdef..." dahinein kopiert. Ab diesem Moment ist der Referenzzähler von result == 1 und es wird NICHTS mehr kopiert. D.h. 26 mal wird nur 1 Zeihen = 1 Byte im String Result mit einem anderen Byte ausgetauscht.

Im ersten Vorschlag sieht die Sache anders aus. Durch Result := Result + x; wird 26 Mal der Speicherbereich in Result um jeweils 1 Zeichen vergrößert. Im schlechtesten Falle muß also Result 25 mal umkopiert werden um Plattz für dieses eine neue Zeichen zu haben. Insgesammt würden dann statt einmal 26 Bytes Kopieren, somit 1+2+3+4+5+6+7+8+9+10+11+12+12+14+15+16+17+18+19+2+ 21+22+23+24+24+25 = 325 Bytes kopiert. Aber diese Kopiererei ist noch nicht alles, denn damit kopiert werden kann benötigt man natürlich zusätzlichen Code der ausgeführt werden muß, was ebenfalls die Performance reduziert. Ein zusätzliches Copy() würde die Sache nochmals ineffizienter machen, da durch das Copy() wiederum eine zusätzliche Stringallokation anfallen würde.

Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:49 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz