Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Randomize: bestimmte Anz von Buchstaben / Zahlen


inkoknito - Mi 08.07.09 15:58
Titel: Randomize: bestimmte Anz von Buchstaben / Zahlen
Hallo,

ich möchte mir mittels randomize ein zufälliges Passwort generieren lassen und habe bisher folgenden Code:


Delphi-Quelltext
1:
2:
3:
4:
5:
    str:='1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    result:='';
    repeat
      result:=result+str[Random(Length(str))+1];
      until(Length(Result)=8);


Randomize wird im OnCreate-Ereignis aufgrufen.

Ich würde jetzt gern festlegen, dass das Passwort aus 3 Zahlen, 3 Großbuchstaben und 2 Kleinbuchstaben bestehen soll. Hab hierfür noch nicht wirklich 'n vernünftigen Anhaltspunkt und hoffe ihr könnt mir hier weiterhelfen!!

Gruß, Jana


R4id - Mi 08.07.09 16:10

Denn Code hast du dir sicherlich im Delphi-Treff aufgegabelt:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
function RandomPassword(PLen:Integer):string;
var
  str:string;
begin
  Randomize;
  //string with all possible chars
  str:='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  Result:='';
  repeat
    Result:=Result+str[Random(Length(str))+1];
  until(Length(Result)=PLen)
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //generate a password with 10 chars
  Label1.Caption:=RandomPassword(10);
end;
Zufallspasswort generieren [http://www.delphi-treff.de/tipps/object-pascal/wiki/Zufallspasswort%20generieren/]

Du musst mit zählen wie viele große Zeichen, kleine Zeichen und Zahlen du hast.


thepaine91 - Mi 08.07.09 16:25

Hi,

mach es doch einfach wie im Link.
1 upper ein lower ein Zahlen string.
So schreibst die in einen Array.
Dann generierst du die Zufallszahlen in der Länge des Arrays und kürzt dann immer die Position der Zahl ausm Array raus bis alles weg ist. Und schon hast du dein Passwort.
Und sichere Passwörter sollten ca. 10 Zeichen und Sonderzeichen beinhalten. ( ! etc.)


inkoknito - Mi 08.07.09 17:10

Hallo Ihr beiden,

vielen Dank für eure Hilfe.

@R4id --> habe ich aus einem Forum, stimmt :) Der Link von dir kam mir allerdings nicht so bekannt vor. Die Funktion mit den unterteilten Groß-, Kleinbuchstaben und Zahlen hat mir aber sehr weitergeholfen. Da ich nicht so der Profi bin wusste ich nicht wirklich wie ich die Anz der jeweiligen Buchstaben zählen soll.

@thepaine92 --> vielen Dank auch an Dich. Hab es nun nicht mit einem Array gelöst sondern mit einem normalen String. Schreibe hier 2 x klein, 3 x groß, 3 x Zahlen und mische diesen String dann nochmal (code ebenfalls hier im Forum)

Die Sicherheit der Passwörter ist momentan für meine Bedürfnisse nicht sooo wichtig :)

Hier mein Code der Funktion:


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:
function GeneratePassword(Mode: TPasswordMode):string;
const
  cLower   = 'abcdefghjkmnpqrstuvwxyz';
  cUpper   = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
  cNumbers = '123456789';

var
  i, j : Integer;
  s, pwd : string;
  ch, ch2 : char;
  iM: BYTE;
begin
  // Kein mode angegeben, dann raus...
  if Mode = [] then Exit;

  i := 0;
  Randomize;

  //ersten 2 Zeichen Kleinbuchstaben
  while (i < 2do
  begin
    if (pmLower in Mode) then begin
            s := s + cLower[1+RANDOM(Length(cLower))];
           Inc(i);
    end;
  end;

  //nächsten 3 Zeichen Großbuchstaben
  while (i < 5do
  begin
    if (pmUpper in Mode) then begin
            s := s + cUpper[1+RANDOM(Length(cUpper))];
           Inc(i);
    end;
  end;

  //letzten 3 Zeichen Zahlen
  while (i < 8do
  begin
    if (pmNumbers in Mode) then begin
            s := s + cNumbers[1+RANDOM(Length(cNumbers))];
           Inc(i);
    end;
  end;

  //Mischen des Strings
  for i := 0 to length(s) do begin
       j := random (length(s)+1);
       if (i > 1and (j > 1then begin
         ch   := s[j];
         ch2  := s[i];
         s[i] := ch;
         s[j] := ch2;
      end;
    end;
  Result := s;
end;


Vielleicht nicht die eleganteste Lösung aber sie erfüllt Ihren Zweck!!

Danke!!


Marc. - Mi 08.07.09 17:28


Delphi-Quelltext
 
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
{ ... }
  i := 0;
  Randomize;

  //ersten 2 Zeichen Kleinbuchstaben
  while (i < 2do
  begin
    if (pmLower in Mode) then 
    begin
       s := s + cLower[1+RANDOM(Length(cLower))];
       Inc(i);
    end;
  end;

Was passiert denn, wenn pmLower nicht gesetzt ist? :zwinker:
Gilt auch sowohl für pmUpper, als auch für pmNumbers.


Delphi-Quelltext
 
47:
48:
49:
{ ... }
  for i := 0 to length(s) do begin
       j := random (length(s)+1);
       if (i > 1and (j > 1then begin

String-Indizes beginnen übrigens bei 1, damit erübrigt sich u.a. ein Teil deiner If-Abfrage...

Grüße,
Marc


pigfacejoe - Mi 08.07.09 17:43

Hallo,
ist es da nicht evtl. leichter einfach per Zufall Zahlen des Ascii Codes zu generieren und die zugehörigen Zeichen dann zu nehmen?

also in etwa so:

Delphi-Quelltext
1:
2:
3:
4:
5:
randomize;
pw:='';
for z:= 1 to n do
pw:=pw+chr(random(255));
end;


Wenn du irgendwelche Vorschriften hast (z.B letzten 3 Zeichen müssen Zahlen sein oder so), kannste das ja einfach anpassen.

Gruß
Max


Xentar - Mi 08.07.09 17:57


Delphi-Quelltext
1:
2:
3:
4:
const
  cLower   = 'abcdefghjkmnpqrstuvwxyz';
  cUpper   = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
  cNumbers = '123456789';

Ist das eigentlich gewollt, dass da einige Buchstaben und eine Zahl fehlt?


inkoknito - Do 09.07.09 15:41

@Xentar

Ja, ist gewollt weil in der ausgedruckten Schriftart teilweise 0 und O und 1 und l und I etc. nicht klar zu unterscheiden sind (die 1 musste eigentlich auch noch raus) :)

@Marc

Da der Nutzer hier nicht selbst entscheidet, welcher Mode gewählt ist rufe ich die Funktion immer mit allen 3 auf. Wäre sicherlich dann auch ohne diese Parameterübergabe gegangen.

@pigfacejoe

Deine Lösung sieht auch schön schlank aus. Werde ich auf jeden Fall auch mal ausprobieren. Danke dafür!


Marc. - Do 09.07.09 16:55

user profile iconinkoknito hat folgendes geschrieben Zum zitierten Posting springen:
Da der Nutzer hier nicht selbst entscheidet, welcher Mode gewählt ist rufe ich die Funktion immer mit allen 3 auf. Wäre sicherlich dann auch ohne diese Parameterübergabe gegangen.

Ich wollte dir damit klar machen, dass dein Konstrukt, im Fall pmXXX nicht Element von Mode, zu einer Endlosschleife führen sollte.