Logo faq-o-matic.net
Logo faq-o-matic.net

VB-Skripts für Windows 2000ff und Active Directory

von veröffentlicht am10. September 2003, 15:30 Uhr Kurzlink und Zitatlink einblenden
Kategorie Kategorie: Downloads, Scripting, VBScript   Translate with Google Translate Translate EN   Die angezeigte Seite drucken
Zuletzt aktualisiert: 15. April 2008

Hier findet ihr eine Reihe von VB-Skripts (Visual Basic Scripts) für Windows 2000 und Active Directory. Sie dienen in erster Linie zu Demonstrationszwecken, sollen aber auch einige typische administrative Aufgaben erleichtern. Es handelt sich um frühe Versuche, also erwartet bitte nichts allzu Tolles! 😉

Alle Dateien laufen unter Windows 2000 und setzen zum Teil eine vorhandene Active-Directory-Domäne voraus. Die Skripts sind Public Domain, d.h. ihr könnt sie gern verwenden und verändern. Sie können als Zip-Datei heruntergeladen werden:

Download: VB-Skripts für Windows und Active Directory  VB-Skripts für Windows und Active Directory (3,9 KiB, 11.356-mal heruntergeladen, letzte Änderung am 23. November 2002)

Achtung: Ich übernehme keine Gewähr für die Funktion oder für eventuelle Fehler! Die Benutzung dieser Skripts geschieht vollständig auf eigene Gefahr!

Folgende Skripts findet ihr hier:

  • Ausgeben einer kompletten Ordnerstruktur in eine Textdatei
  • Anlegen von Benutzern mit Telefonnummer (Beispiel, Teil 1)
  • Ändern der Telefonnummer bei allen Benutzern (Beispiel, Teil 2)
  • Ändern des Anmeldenamens
  • Anlegen zahlreicher Benutzer zu Testzwecken
  • Passwort bei allen Benutzern einer OU ändern

Und auf weiteren Seiten gibt es Beispiele, wie das AD-Schema erweitert werden kann und wie man die AD-Konfiguration bearbeitet.


Ausgeben einer kompletten Ordnerstruktur in eine Textdatei

Dieses Beispiel zeigt den Umgang mit dem Dateisystem (und nebenbei auch den Trick, wie man verschachtelte Strukturen mit rekursiven Aufrufen behandeln kann). Es liest von einem beliebigen Ordner aus alle Unterordner komplett aus und schreibt diese in eine Textdatei. Diese Datei kann man dann z. B. zu Dokumentationszwecken nutzen.

>> Zur Erläuterung

 1. drive=InputBox("Bitte Startordner eingeben!","Ordnerstruktur2Text") 
 2. ordner = "Root" & vbCrLf 
 3. dateiname = "Ordnerstruktur2Text.txt" 
 4. ebene = 0 

 5. ' Dateisystem-Zugriff ermöglichen: 
 6. set fs = CreateObject("Scripting.FileSystemObject") 

 7. ' existiert der angegebene Ordner überhaupt? 
 8. if fs.FolderExists(drive) then 

 9.	' Ausgabedatei 
10.	outputname = fs.Buildpath(drive, dateiname) 
11.	set output = fs.CreateTextFile(outputname) 

12.	' Startordner ansprechen 
13.	set folder = fs.GetFolder(drive) 

14.	' alle Unterordner des Ordners ausgeben: 
15.	listFolder(folder) 
16. else 
17.	msgBox "Den Startordner gibt es gar nicht!",vbCritical,"Ordnerstruktur2Text" 
18.	wscript.quit 
19. end if 

20. ' Ergebnis in die Datei schreiben 
21. output.write Ordner 
22. output.close 

23. ' Erfolg melden 
24. Nachricht = "Fertig." & vbCrLf & vbCrLf 
25. Nachricht = Nachricht & "Datei gespeichert als:" & vbCrLf 
26. Nachricht = Nachricht & outputname 
27. msgBox Nachricht,,"Ordnerstruktur2Text" 

28. sub listFolder(folder) 
29.	' Ordnerebene 
30.	ebene = ebene + 1 

31.	' Fehlerbehandlung aus, falls Berechtigungen fehlen 
32.	on error resume next 

33.	' keine Unterordner? Dann zurück 
34.	if folder.subfolders.count = 0 then 
35.		ebene = ebene - 1 
36.		on error goto 0 
37.		exit sub 
38.	end if 

39.	' Unterordner auflisten und ggf. auch deren Unterordner ... 
40.	for each subfolder in folder.subfolders 
41.		' mit Tabs einrücken 
42.		tabs = string(ebene, vbTab) 
43.		ordner = ordner & tabs & subfolder.name & vbCrLf 
44.		' Rekursion durch Unterordner 
45.		listFolder(subfolder) 
46.	next 

47.	' Fehlerbehandlung wieder an ... 
48.	on error goto 0 

49.	' ... und eine Ebene hoch 
50.	ebene = ebene - 1 
51. end sub

Erläuterung: Zeilen 1 bis 4 legen einige Werte fest (der Startordner wird vom Benutzer abgefragt). Der Zugriff auf das Dateisystem geschieht über das „Scripting.FileSystemObject“, über welches auch geprüft wird, ob es den Startordner überhaupt gibt (8). Falls nicht, wird unter „else“ das Skript mit Fehlermeldung beendet (16-18).

Ansonsten wird die Ausgabedatei angelegt (10/11), und es geht los mit dem Aufruf der eigentlichen Funktion (15).

Prozedur „listFolder“ (28-51): Um die ausgegebenen Ordner in der Textdatei passend einzurücken, wird in der Variablen „ebene“ die Schachtelungstiefe gemessen. Für jeden Unterordner wird sie um eins erhöht. Falls keine Zugriffsberechtigung auf einen Ordner vorhanden ist (Windows NT/2000/XP/.NET), würde das Skript abbrechen, daher wird hier die Fehlerbehandlung kurzerhand abgeschaltet (32). Sollte der aktuelle Ordner gar keine Unterordner haben, springt das Skript wieder zurück (34-38). Die Schleife in Zeilen 40 bis 46 erledigt die eigentliche Arbeit: Sie schreibt nicht nur den Namen jedes Unterordners in die Variable „Ordner“ (43), sondern sorgt über die „String“-Funktion für die passende Einrückung (pro Ebene ein Tabulator; 42). Der eigentliche Kniff folgt aber in Zeile 45: Für jeden Unterordner ruft die Funktion sich hier selbst auf und wandert so rekursiv durch alle Ordner, egal, wie tief (oder wie flach) die Verschachtelung ist. Sind alle Ordner einer Ebene durchlaufen, so schließt die Schleife ab und reduziert den Ebenenzähler wieder um eins (50).

Zum Abschluss wird die gefüllte Variable „Ordner“ in die Datei kopiert (21) und der Benutzer über deren Speicherort informiert (24-27).


Anlegen von Benutzern mit Telefonnummer (Beispiel, Teil 1)

In diesem ADSI-Beispiel (Active Directory Service Interface) geht es um folgendes Szenario:

Eine Firma bekommt eine neue Telefonanlage. Dadurch ändert sich bei allen Nutzern die Durchwahl. Dies manuell bei allen Benutzern zu ändern, wäre ein riesiger Aufwand. Per Skript erledigt dies eine kleine Schleife.

Dieses erste Skript dient nun dazu, Benutzerkonten mit einer Beispiel-Telefonnummer anzulegen, damit das eigentliche Beispiel angewandt werden kann:

 1.   dim rootDSE 
 2.   set rootDSE = GetObject("LDAP://RootDSE") 
 3.   domainname=rootDSE.Get("defaultnamingcontext") 

 4.   set domain = GetObject("LDAP://" & domainname) 

 5.   ' Neuen Benutzernamen erfragen 
 6.   Nutzer = InputBox("Benutzername?") 

 7.   ' Telefonnummer aufbauen: 4711 plus 1 Zufallsziffer 
 8.   Telefon = "4711" 
 9.   Randomize 
10.   Telefon = Telefon & CInt(rnd(1)*10) 

11.   ' User anlegen 
12.   Set usr = domain.Create("user", "CN=" & Nutzer & ",OU=Hardware") 
13.	usr.Put "samAccountName", Nutzer 
14.	usr.Put "userAccountControl", 512 
15.	usr.Put "telephoneNumber", Telefon 
16.	usr.SetInfo 
17.	usr.SetPassword "geheim"

Erläuterung: Hier wird ein einzelnes Benutzerkonto angelegt. Dazu wird, nach Verbindung mit der AD-Domäne (Zeilen 1 bis 4), ein Benutzername angefragt. Sodann wird eine (teilweise zufällige) Telefonnummer generiert (8 bis 10). Dann wird der Benutzer angelegt (12 bis 17), und zwar nur mit den hier wichtigen Eigenschaften.


Ändern der Telefonnummer bei allen Benutzern (Beispiel, Teil 2)

Hier der zweite Teil, in dem es ernst wird: Erweitere die Telefonnummer jedes Benutzers um das Präfix „123“.

>> Zur Erläuterung

 1.   set objRoot = GetObject("LDAP://rootDSE") 
 2.   strDomain = objRoot.Get("DefaultNamingContext") 
 3.   strOU = InputBox("Welche OU?") 
 4.   strObjOU = "LDAP://OU=" & strOU & "," & strDomain 
 5.   set objOU = GetObject(strObjOU) 

 6.   for each varUser in objOU 
 7.	set objUser = GetObject("LDAP://" & varUser.Name & ",OU=" & strOU & "," & strDomain) 
 8.	objUser.GetInfo 
 9.	strTelAlt = objUser.Get("telephoneNumber") 
10.	strTelNeu = "123" & strTelAlt 
11.	objUser.Put "telephoneNumber", strTelNeu 
12.	objUser.SetInfo 
13.   next

Erläuterung: Nach Verbindung zum AD (1/2) wird die OU abgefragt (3) und ausgelesen (4/5). Sodann geht eine Schleife alle Objekte durch (6-13), liest die Telefonnummer aus (9) und setzt das Präfix davor (10). Danach wird die Nummer geändert (11) und das Objekt geschrieben (12).

Das Skript setzt voraus, dass in der fraglichen OU nur Benutzerkonten liegen (keine Gruppen usw.) und dass jedes Konto eine Telefonnummer hat. Diese Einschränkung wurde aus Gründen der Übersichtlichkeit gemacht und ließe sich recht leicht umgehen (vgl. dazu das Beispiel „PasswordChanger“).

Anmerkung: Dieses Beispiel ist leicht variiert übernommen aus Michela/Palme: Active Directory, Microsoft Press 1999.


Ändern des Anmeldenamens

Eine Variante des Telefon-Beispiels ist dieses: Bei allen Benutzern einer anzugebenden OU soll der Anmeldename nach einem festen Schema geändert werden. Dabei sollen der Windows-2000-basierte Name (User principal Name, UPN) und der NT-basierte Name (SAM-Anmeldename) gleich sein. Eine solche Anforderung trifft man oft in Migrationsprojekten an, wo im Zuge der Migration von Benutzerkonten auch die Anmeldenamen vereinheitlicht werden sollen.

Das Schema, das hier genutzt wird, ist „Vorname.Nachname“. Falls diese Kombination länger ist als 20 Zeichen (was bei NT-Namen unzulässig wäre), wird sie gekürzt auf die ersten 20 Zeichen von „V.Nachname“. Umlaute werden dabei automatisch umgeschrieben.

Diese Lösung prüft allerdings nicht die Eindeutigkeit der Namen. Außerdem bricht das Skript ab, wenn es auf ein Objekt ohne Anmeldenamen stößt (etwa einen Kontakt). Das lässt sich aber leicht durch eine Prüfung verhindern.

>> Zur Erläuterung

 1. ''''''''''''''''''''''''''''''''''''''''''''' 
 2. ' LogonNameÄndern.vbs 
 3. ' 
 4. ' Ändert den SAM-Logon-Namen und den UPN 
 5. ' von Benutzerkonten einer anzugebenden OU 
 6. ' ins Format "Vorname.Nachname". Umlaute 
 7. ' werden umgeschrieben. 
 8. ' 
 9. ' Von Nils@Kaczenski.de 
10. ' 
11. ' Keine Gewähr! Nutzung auf eigene Gefahr! 
12. ' 
13. ''''''''''''''''''''''''''''''''''''''''''''' 

14. ' Verbindung zur Domäne 
15. set objRoot = GetObject("LDAP://rootDSE") 
16. strDomain = objRoot.Get("DefaultNamingContext") 

17. ' Benutzer fragen ... 
18. strOU = InputBox("Welche OU soll bearbeitet werden?") 
19. strUPNDomain = InputBox("Wie soll die UPN-Domäne heißen?",,"@domain.dom") 

20. ' Verbindungsstring 
21. strObjOU = "LDAP://OU=" & strOU & "," & strDomain 

22. ' OU ansprechen 
23. set objOU = GetObject(strObjOU) 

24. intZahl = 0 

25. ' alle Objekte bearbeiten 
26. ' muss evtl. auf geeignete Objekttypen beschränkt werden 
27. for each varUser in objOU 
28. 	set objUser = GetObject("LDAP://" & varUser.Name & ",OU=" & strOU & "," & strDomain) 
29. 	objUser.GetInfo 
30. 	strNachname = objUser.Get("sn") 
31. 	strVorname = objUser.Get("givenName") 

32.	    strNachname = Umlaute(strNachname) 
33.	    strVorname = Umlaute(strVorname) 

34.	    ' Länge auf 20 Zeichen begrenzen (SAM-Namen) 
35.	    if len (strVorname & "." & strNachname) <= 20 then 
36.	       strSAMNeu = strVorname & "."   & strNachname 
37.	    else 
38.	       strSAMNeu = left(strVorname,1) & "."   & left(strNachname,18) 
39.	    end if 

40.	    ' UPN zusammenbauen 
41.	    strUPNNeu = strSAMNeu & strUPNDomain 

42.	    ' Neue Namen schreiben 
43. 	objUser.Put "sAMAccountName", strSAMNeu 
44. 	objUser.Put "userPrincipalName", strUPNNeu 
45. 	objUser.SetInfo 
46.	    intZahl = intZahl + 1 
47. next 

48. ' Erfolgsmeldung ausgeben 
49. msgBox intZahl & " Benutzer bearbeitet." 

50. function Umlaute(strText) 
51.	' Funktion: schreibt Umlaute und Sonderzeichen um 
52.	' Eingabeparameter: strText: zu ändernder String 
53.	' Kommentar: 

54.	strText = replace(strText, "Ä", "Ae") 
55.	strText = replace(strText, "Ö", "Oe") 
56.	strText = replace(strText, "Ü", "Ue") 

57.	strText = replace(strText, "ä", "ae") 
58.	strText = replace(strText, "ö", "oe") 
59.	strText = replace(strText, "ü", "ue") 
60.	strText = replace(strText, "ß", "ss") 

61.	Umlaute = strText 

62. end function

Erläuterung: Die Zeilen 14 bis 23 tun dasselbe wie die Zeilen 1 bis 5 im vorigen Beispiel. Die Variable „intZahl“ zählt einfach mit (24, 46 und 49).

In den Zeilen 27 bis 47 wird eine ähnliche Schleife wie im vorigen Beispiel durchlaufen: Für jeden Benutzer werden Vor- und Nachname ausgelesen (30/31). In zwei Variablen wird der neue Name von Umlauten bereinigt (32/33), geprüft und dann zusammengebaut (34-41). Dann werden die beiden Namen in die Benutzereigenschaften geschrieben (43-45).

Die Funktion „Umlaute“ (50-62) bereinigt mit der „replace“-Funktion den übergebenen String um Umlaute.


Anlegen zahlreicher Benutzer zu Testzwecken

Dieses Skript ist in der Test- und Laborpraxis sehr nützlich: Es legt in einer gegebenen OU massenhaft Benutzerkonten an. Hier ohne weitere Attribute, aber das lässt sich ja leicht ergänzen.

>> Zur Erläuterung

 1.   dim rootDSE 
 2.   set rootDSE = GetObject("LDAP://RootDSE") 
 3.   domainname=rootDSE.Get("defaultnamingcontext") 
 4.   set domain = GetObject("LDAP://" & domainname) 

 5.   Anzahl = inputBox("Wie viele User?") 
 6.   ZielOU = inputBox("In welcher OU sollen die User angelegt werden?") 

 7.   randomize 
 8.   Zufallszahl = Int(100 * rnd + 1) 

 9.   i = 0 
10.   do until i > Anzahl - 1 
11.	MUsername = "MassenUser" & Zufallszahl & "-" & i 
12.	Set usr = domain.Create("user", "CN=" & MUsername & ", OU=" & ZielOU) 
13.	usr.Put "samAccountName", MUsername 
14.	usr.Put "userPrincipalName", MUsername & "@domain.dom" 
15.	usr.Put "userAccountControl", 512 
16.	usr.SetInfo 

17.	set usr = nothing 
18.	i = i+1 
19.   loop 

20.   set domain = nothing 

21.   if i>0 then 
22.	Erfolg = "Fertig: " & i & " User angelegt (Massenuser" 
23.	Erfolg =  Erfolg & Zufallszahl & "-0 bis " & i-1 & ")." 
24.   else 
25.	Erfolg = "Keine User angelegt." 
26.   end if 

27.   msgBox(Erfolg)

Erläuterung: Auch hier wieder erst die Verbindung zum AD (1 bis 4). Dann Abfrage der Ziel-OU und der Anzahl gewünschter Benutzer (5/6). Damit man das Skript mehrfach anwenden kann, wird dann eine Zufallszahl zwischen 1 und 100 generiert, die hinterher an die Benutzernamen angehängt wird (7/8). Dann die eigentliche Schleife (9 bis 19): Aufbau des Nutzernamens mit Zufallszahl und fortlaufender Nummer („MassenUser17-1“; Zeile 11), dann Anlegen des Kontos in der Ziel-OU (12) und Angabe der wichtigen Attribute (13-15). Mit „SetInfo“ wird das Objekt dann vom Cache ins AD übertragen (16). Am Ende wird nur noch aufgefäumt (20) und der Benutzer über den Erfolg informiert (21-27).


Passwort bei allen Benutzern einer OU ändern (PasswordChanger)

Hier nun ein (wie ich finde) besonderes Bonbon: Manchmal muss man für eine größere Zahl von Benutzerkonten ein neues Passwort vergeben. Das kann vorkommen, wenn man einen Einbruch in die Domäne vermutet, aber auch, wenn man eine größere Zahl von Konten aus einer Textdatei importiert hat.

Dieses Skript generiert für alle Benutzer einer OU ein neues, zufälliges Passwort. Dabei wird dieses Passwort so aufgebaut, dass es auch strengen Richtlinien genügt („starkes“ Passwort aus vier Zeichensorten: Groß- und Kleinbuchstaben, Ziffern, Sonderzeichen). Damit man nun hinterher auch weiß, wer welches Passwort hat, werden die Passwörter in eine Datei geschrieben, die man dann z. B. mit Excel öffnen kann. Die Datei liegt im Ordner %systemroot%PWC; es empfiehlt sich, diesen Ordner mit Berechtigungen zu schützen.

>> Zur Erläuterung

 1.   ' Verbindung 
 2.   set objRoot = GetObject("LDAP://rootDSE") 
 3.   strDomain = objRoot.Get("DefaultNamingContext") 

 4.   ' Zugriff aufs Dateisystem 
 5.   set fso = CreateObject("Scripting.FileSystemObject") 
 6.   with fso 
 7.	systemPfad = .GetSpecialFolder(WindowsFolder) 
 8.	dateiPfad = .BuildPath(systemPfad, "PWC") 
 9.	if not .FolderExists(dateiPfad) then .CreateFolder(dateiPfad) 
10.	dateiName = "PWC" & CStr(Now) & ".csv" 
11.	dateiName = replace(dateiName, ":", "-") 
12.	pfadName = .BuildPath(dateiPfad, dateiName) 
13.	set datei = .CreateTextFile(pfadName) 
14.   end with 
15.   datei.WriteLine "DN,password" 

16.   ' OU-Auswahl 
17.   strOU = InputBox("Welche OU?") 
18.   strObjOU = "LDAP://OU=" & strOU & "," & strDomain 

19.   Laenge = InputBox("Wie lang soll das Passwort sein (min. 4 Zeichen)?") 

20.   set objOU = GetObject(strObjOU) 
21.   for each varUser in objOU 
22.	set objUser = GetObject("LDAP://" & varUser.Name & ",OU=" & strOU & "," & strDomain) 
23.	objTyp = objUser.GetEx("objectClass") 
24.	AttrZahl = UBound(objTyp) 
25.	objUserTest = objTyp(AttrZahl) 
26.	if objUserTest = "user" then SetzePasswort(Laenge) 
27.   next 
28.   MsgBox("Passwortdatei wird gespeichert unter: " & vbCrLf & pfadName) 

29.   datei.close 

30.   sub SetzePasswort(PLaenge) 
31.	objUser.GetInfo 
32.	objUName = objUser.Get("distinguishedName") 
33.	NeuPass = Kennwort(PLaenge) 
34.	objUser.SetPassword NeuPass 
35.	objUser.SetInfo 

36.	datei.WriteLine (chr(34) & objUName & chr(34) & "," & chr(34) & NeuPass & chr(34)) 

37.   end sub 

38.   function Kennwort(Anzahl) 
39.	if Anzahl > 128 then Anzahl = 128 
40.	Wort = "" 
41.	Wort = Zeichen(48, 57) ' Ziffern 
42.	Wort = Wort & Zeichen(65, 90) ' Großbuchstaben 
43.	Wort = Wort & Zeichen(97, 122) ' Kleinbuchstaben 
44.	Wort = Wort & Zeichen(33, 47) ' Satzzeichen 
45.	if Anzahl > 4 then 
46.		for i = 5 to Anzahl 
47.		Wort = Wort & Zeichen (33, 122) 'sonstige Zeichen 
48.		next 
49.	end if 
50.	Wort = Verschiebe(Wort) ' Zeichenfolge zufällig ändern 
51.	Kennwort = Wort 
52.   end function 

53.   function Zeichen(Anfang, Ende) 
54.	randomize 
55.	Zufall = Int((Ende - Anfang +1) * rnd + Anfang) 
56.	Zeichen = chr(Zufall) 
57.   end function 

58.   function Verschiebe(VWort) 
59.	WLaenge = len(VWort) 
60.	NeuWort = "" 
61.	ReDim WFeld (WLaenge) 
62.	for i = 1 to WLaenge 
63.		WFeld(i) = mid(VWort, i, 1) 
64.	next 
65.	zahl = 0 
66.	do until len(NeuWort) = WLaenge 
67.		randomize 
68.		j = Int((WLaenge) * rnd + 1) 
69.		if WFeld(j) <> "" then 
70.			NeuWort = NeuWort & WFeld(j) 
71.			WFeld(j) = "" 
72.		end if 
73.	zahl = zahl + 1 
74.	if zahl > 1000 then exit do ' Zur Sicherheit 
75.	loop 
76.	Verschiebe = NeuWort 
77.   end function

Erläuterung: Dieses Skript ist etwas komplexer; daher nur kurze Hinweise:

Verbindung zum AD (1/2), dann Anlegen der Passwortdatei (4 bis 15) als CSV-Datei. Dazu wird, falls noch nicht vorhanden, der Ordner %systemroot%\PWC angelegt (7 bis 9). Die Datei selbst wird mit Datum und Uhrzeit benannt, damit mehrere Durchgänge möglich sind (10 bis 13).

Abfrage von OU und Passwortlänge (17 bis 19), dann die wesentliche Schleife, die alle Objekte der Ziel-OU ausliest (21 bis 27). Hierbei werden nur Benutzerkonten angesprochen, was etwas umständliches Auslesen der Objektklasse erfordert, die bei „echten“ Benutzern mehrteilig ist (Computerkonten sind intern auch Benutzer, haben aber kein Passwort!). Das eigentliche Passwort wird dann mit der Prozedur „SetzePasswort“ erzeugt (26).

Prozedur „SetzePasswort“ (30 bis 37): Erwartet die Angabe der Passwortlänge. Liest den Benutzernamen aus (einzig zu dem Zweck, den Namen in die Passwortdatei zu schreiben; Zeile 32 und 36). Das Passwort selbst wiederum wird mit der Funktion „Kennwort“ generiert und dann geschrieben (33/34).

Funktion „Kennwort“ (38 bis 52): Erwartet die Angabe der Passwortlänge. Prüft erst die Maximallänge (39) und generiert dann die ersten vier Zeichen; eines pro Zeichensorte. Daraus erklärt sich die Minimallänge von 4 Zeichen (40 bis 44). Falls mehr als 4 Zeichen gewünscht sind, werden die weiteren Zeichen über die Funktion „Zeichen“ generiert. Dieser Aufbau stellt sicher, dass auf jeden Fall vier Zeichensorten auftauchen, auch wenn die weiteren Zeichen alle derselben Sorte entspringen sollten (45 bis 49). Danach wird mit der Funktion „Verschiebe“ die Reihenfolge der Zeichen noch mal per Zufall verschoben, damit nicht immer dieselbe Folge von Zeichensorten auftaucht (wäre ein Angriffspunkt; Zeile 50).

Funktion „Zeichen“ (53 bis 57): Erwartet die Angabe eines Zeichenbereichs (ASCII-Bereich) über das erste und das letzte ASCII-Zeichen. Dann wird aus dem gegebenen Bereich ein zufälliges Zeichen zurückgegeben.

Funktion „Verschiebe“ (58 bis 77): Erwartet ein Wort als Parameter. Die Funktion verschiebt alle Buchstaben des Wortes an zufällige neue Positionen. Für das Wort wird ein Array generiert, das in jedes Feld genau ein Zeichen des Wortes ablegt (59 bis 64). Dann wird dieses Array durchlaufen: Per Zufall wird ein Feld des Array ausgewählt (67/68). Wenn es nicht leer ist, wird das Zeichen aus diesem Feld an das neue Wort angehängt. Danach wird das Feld gelöscht (69 bis 72). Auf diese Weise ist sichergestellt, dass jedes Zeichen nur einmal im neuen Wort landet. Das wird so lange wiederholt, bis alle Zeichen des alten Wortes im neuen Wort gelandet sind. Da eine solche Schleife immer etwas gefährlich ist, wird sie nach spätestens 1000 Umdrehungen abgebrochen (73/74). Diese Funktion ist vielleicht nicht besonders elegant und mit Sicherheit nicht allzu performant. Sie skizziert aber, wie man in einer einfachen Skriptsprache ein solches Problem lösen kann. (Falls jemand Besseres vorzuschlagen hat, freue ich mich!)

© 2005-2023 bei faq-o-matic.net. Alle Rechte an den Texten liegen bei deren Autorinnen und Autoren.

Jede Wiederveröffentlichung der Texte oder von Auszügen daraus - egal ob kommerziell oder nicht - bedarf der ausdrücklichen Genehmigung durch die jeweiligen Urheberinnen oder Urheber.

Das Impressum findet sich unter: http://www.faq-o-matic.net/impressum/

Danke, dass du faq-o-matic.net nutzt. Du hast ein einfaches Blog sehr glücklich gemacht!