146. Überprüfung von Input oder Passwort mit CMD/Batch
Einleitung
Ab und zu ist es sinnvoll die Eingaben eines Users auf die Validität zu
überprüfen. Das geht zwar einfacher mit VBS, aber hier wird eine
Variante mit einer Batch vorgestellt, die Sie nach Erklärung beliebig
anwenden können.
Die Länge eines Passwortes ist relativ leicht bestimmbar, aber bei der
Bestimmung von Textinhalten mit Batch sind Sonderzeichen ein Problem.
Des weiteren gibt es unterschiedliche Bedürfnisse des Admininistrators,
ob nur bestimmte Zeichen oder der gesamte Inhalt überprüft wird.
Mit der folgenden Batch können Sie durch geringfügige Änderungen fast
alle Prüfungen mit wenigen Änderungen durchführen.
Die Abhandlung ist für fortgeschrittene Batchschreiber bestimmt,
da ein Anfänger lieber kleinere Herausforderungen suchen sollte.
---
Wir brauchen zwei Dokumente: Ein Textdokument mit 5 Zahlen in
einer Zeile (irgendwo einen Buchstaben als Falscheingabe einfügen), die
Sie auswählen können. Das Textdokument muss den Namen password.txt haben oder Sie ändern den Namen in der vierten Zeile dementsprechend um.
Dann eine Batch mit beliebigen Namen. In diese
kopieren Sie den folgenden Text:
set destination=%~dp0%
set /a yzahl=1
Set eu1strang=
set /p passneunvar=<password.txt
:oopneun
set lpstrang1=0,%yzahl%%%
set lpstrang2=-1%%
>"%destination%lpha.bat"
ECHO set destination=%%~dp0%%
>>"%destination%lpha.bat"
ECHO set trang=%passneunvar%
>>"%destination%lpha.bat"
ECHO set trang=%%trang:"=yzahl%%
>>"%destination%lpha.bat"
ECHO set trang1=%%trang:~%lpstrang1%%
>>"%destination%lpha.bat"
ECHO set eu1strang=%%eu1strang%%%%trang1%%
>>"%destination%lpha.bat"
ECHO if "%%eu1strang%%"=="%%trang%%" echo aus ^>aus.txt
>>"%destination%lpha.bat"
ECHO set tring=%%trang1%%
>>"%destination%lpha.bat"
ECHO tring=%%tring:"=yzahl%%
>>"%destination%lpha.bat"
ECHO set tring2=%%tring:~%lpstrang2%%
>>"%destination%lpha.bat"
ECHO set roofgo=%%tring2%%
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "1 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "2 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "3 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "4 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "5 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "6 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "7 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "8 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat" ECHO if
"%%roofgo%%" == "9 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO exit
start /wait lpha.bat
timeout /1
if not exist vgl.txt echo Ein
unbekannter Buchstabe wurde verwendet >fehler.txt
del vgl.txt
if exist aus.txt goto
endepsneun
set /a yzahl=%yzahl%+1
goto oopneun
:endepsneun
echo.%yzahl%
>auswertung.txt
del aus.txt
del lpha.bat
if %yzahl% EQU 5 echo o.k. >pos.txt
if %yzahl% NEQ 5 echo Buchstabenzahl stimmt nicht
>neg.txt
if exist neg.txt start ""
"%windir%\system32\notepad.exe" "%destination%neg.txt"
if exist fehler.txt start ""
"%windir%\system32\notepad.exe" "%destination%fehler.txt"
---
So, wir haben jetzt zwei Stränge, von denen der blaue Strang eine
inhaltliche Prüfung übernimmte und der violette Strang den Inhalt
überprüft. Rot sind die Punkte, an denen Sie mit leichten Änderungen
die Prüfung verändern können.
---
Wie arbeitet die Batch?
Der violette Strang ist erstmal leichter und sinnvoller, da die Länge von ihnen nur
durch zwei Eingaben verändert werden kann...
Nach Bestimmung des Standortes der Batch (set destination=%~dp0%) wird
für die Anzahl der Buchstaben des Wortes erstmal erstmal auf 1 gesetzt ( set /a yzahl=1).
Der einzeilige Passworttext (mehr als eine
Zeile funktioniert nicht! set
/p passneunvar=<password.txt) muss erst mal von ihnen erstellt werden. geben Sie vielleicht erstmal 12r4
ein, um das Prinzip zu verstehen: Das r und die Anzahl der Zeichen ist
falsch, da es fünf Zahlen sein sollten und eine Zahl aus dem Bereich
1-9.
Das geht mit leichten Anpassungen auch mit Buchstaben inkluseive €@
usw., es gibt aber auch Ausnahmen. Es wird mit einer Positivliste
(zeichen werden mit einer Positivlste abgeglichen, Wortlänge mit einer
Negativliste) und einer Negativliste gearbeitet.
Das ist im Handumdrehen änderbar...
Danach geht es in eine Schleife, wie Sie es leicht an dem Anfangspunkt ( :oopneun) leicht
erkennen können.
Die folgende Variable können Sie nur verstehen, wenn wir ein wenig
vorgreifen (set
lpstrang1=0,%yzahl%%%).
Denn das ist die zweite Hälfte eines Batchbefehls, der wieder zu einem
Batchbefehl zusammengesetzt wird ( set
trang1=%%trang:~%lpstrang1%%), wenn eine temporäre Hilfsbatch
geschrieben (>>"%destination%lpha.bat"
ECHO) und ausgeführt wird (
start /wait lpha.bat).
In dieser Hilfsbatch wird in der Schleife ein Buchstabe nach dem
anderen überprüft, bis ein Vergleich herausfindet, dass das Passwort
gleich dem zu überprüfenden String ist (if "%%eu1strang%%"=="%%trang%%" echo
aus ^>aus.txt).
Dadurch wird ein Textdokument geschaffen, dass bei der
Überprüfung am Ende des Dokumentes den Ausstieg aus der Schleife
ankündigt ( if exist aus.txt
goto endepsneun).
Vielleicht die folgenden Zeilen ein wenig mehr erklärt:
>>"%destination%lpha.bat"
ECHO set trang=%passneunvar%
>>"%destination%lpha.bat"
ECHO set trang=%%trang:"=yzahl%%
>>"%destination%lpha.bat"
ECHO set trang1=%%trang:~%lpstrang1%%
>>"%destination%lpha.bat"
ECHO set eu1strang=%%eu1strang%%%%trang1%%
>>"%destination%lpha.bat"
ECHO if "%%eu1strang%%"=="%%trang%%" echo aus ^>aus.txt
In der ersten Zeile wird in die neue Hilfsbatch (>>"%destination%lpha.bat"
ECHO) das Passwort in Klarschrift in der CMD geschrieben, z. B.
12345 (%passneunvar%)
und an die Variable trang
übergeben.
In der zweiten Zeile steht dann in der Hilfbatch mit Namen lpha.bat nach dem Echo
folgender Befehl:
set trang=%trang:"=yzahl%
Sie müssen immer dran denken, dass bei der Übergabe von Variablen die
Prozentzeichen verdoppelt werden und Ausgabezeichen mit einem
Karatzeichen escaped werden müssen. Die Hilfsbatch wird geschrieben und
noch nicht ausgeführt!
Weiter im Text: Die Variable Trang besteht im ersten durchlauf der
Schleife erstmal aus der ersten Hälfte einer Befehlskette, die im
Fachjargon auch Ermittlung von Leftstring genannt wird -hier mal ein
Vollzitat der englischen Erklärung von Stringzerlegung (die Seite sollten Sie kopieren):
set trang=politic
echo.%trang%
set trang=%trang:~0,1%
echo.%trang%
würde den ersten Buchstaben p von politic ergeben.
In der Hilsbatch ist das fast dasselbe, nur das die Zeile: set trang1=%%trang:~%lpstrang1%%
in der Hilfebatch den String set trang=%trang:~0,1% (Richtig, die YZahl ist immer die Zahl nach dem Komma) zusammensetzt.
Mit >>"%destination%lpha.bat"
ECHO set eu1strang=%%eu1strang%%%%trang1%% wird die Variable eu1strang um ein Zeichen(%trang1%) erweitert.
Warum so kompliziert? Die Zahlenvariable mit den zwei
Prozentzeichen (1= %yzahl%)
kann wegen der Prozentzeichen nicht direkt übergeben werden - das endet
im Chaos..
Die letzte übergebene Zeile ist wie gesagt der Ausstieg für die
Schleife im allgemeinen (if
"%%eu1strang%%"=="%%trang%%" echo aus ^>aus.txt) Wenn also
die Schleifenzahl (%yzahl%)
so weit erhöht wurde, dass der ermittelte neue Strang (%eu1strang%) gleich dem
gesamten Variablennamen (%trang%
da steht im Beispiel z. B. 12345) ist, dann wird ein Textdokument
geschaffen (>aus.txt).
Das unterbricht die Schleife. Bei einem fünfstelligen Passwort also set
trang=%trang:~0,5%.
Egal, wir sind ja immer noch beim ersten Durchlauf und gehen ein Stück
weiter. Die Batch wird also mit dem ersten Buchstaben ~0,1 ausgeführt
(1=YZahl) und nun gestartet (start
/wait lpha.bat).
if exist aus.txt goto
endepsneun
set /a yzahl=%yzahl%+1
goto oopneun
Nachdem beim ersten Durchlauf getestet wurde, ob ein aus.txt existiert
(der existiert aber erst wenn %%eu1strang%%"=="%%trang%% )
die Buchstabenkolonne des Ausgangsinput gleich dem Ergebnis der neuen
Variable ist, dann wird die YZahl wieder um eine 1 erhöht und mit
dem Goto-Befehl geht es wieder zum Schleifenanfang.
Wieder wird die Hilfsbatch erschaffen, nur dass YZahl nun 2 lautet. Die
alte Batch wird überschrieben. Nun steht %trang:~0,2% in der
Batch - also beim Wort politic würde nun po geprüft werden. po ist aber
nicht politic, also würde bei diesem Kennwort die Schleife bis politic
(%trang:~0,7%) laufen, bis ein Vergleich politic=politic ergeben würde.
Was haben wir dabei gewonnen? YZahl ist das eigentliche Ergebnis, denn
diese entspricht der Zahl der Buchstaben - egal wie viele Buchstaben...
Nachdem Ausstieg aus der Schleife sind neben den üblichen
Bereinigungsarbeiten nur noch die Befehle:
if %yzahl% EQU 5 echo o.k. >pos.txt
if %yzahl% NEQ 5 echo Buchstabenzahl stimmt nicht
>neg.txt
if exist neg.txt start ""
"%windir%\system32\notepad.exe" "%destination%neg.txt"
erklärungsbedürftig:
Im Fall der Batch wollen Sie,ob der Input (der im Password.txt liegt) fünf Buchstaben hat. Also
brauchen Sie nur noch die YZahl mit der Zahl 5 zu vergleichen (EQU
heißt gleich und NEQ ungleich. Das Ergebnis wird in einen Positivtext
oder Negativtext ausgedrückt.
Zuletzt wird eine Message mit Notepad geöffnet, wenn das Password
falsch war (start ""
"%windir%\system32\notepad.exe" "%destination%neg.txt").
Sie könnten genausogut mit einem if - Befehl den User auffordern, ein
anderes Passwort zu setzen oder mit einem goto - Befehl bis vor den
Schleifenpunkt zurückspringen, um den User zu einer Neuangabe zu
zwingen.
Die Demo geht von einem Textdokument aus, wie das erstellt wurde, hängt von ihrer Batch ab.
Das sind aber alles Grundbefehle, die hier nicht weiter erläutert
werden.
Passem Sie den Zähler ihren Bedürfnissen an und die einfachste
Möglichkeit sind drei kleine Änderungen dieser Batch:
Das Dokument mit den Passworttext können Sie einen beliebigen
Namen geben und die Anzahl der Buchstaben mit der Änderung von 5
auf eine beliebige Zahl ändern...
Also im maximalfall drei Änderungen - das dürfte jeder Anfänger hinbekommen...
---
Die andere Batchhälfte in blau ist schnell erklärt: Den Vortext lesen,
um die Batch insgesamt zu verstehen und dann wird ihnen klar sein, wie
Sie Wörter auf Buchstaben oder Zeichen Prüfen...
>>"%destination%lpha.bat"
ECHO set tring=%%trang1%%
>>"%destination%lpha.bat"
ECHO tring=%%tring:"=yzahl%%
>>"%destination%lpha.bat"
ECHO set tring2=%%tring:~%lpstrang2%%
>>"%destination%lpha.bat"
ECHO set roofgo=%%tring2%%
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "1 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "2 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "3 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "4 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "5 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "6 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "7 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "8 " echo o.k. ^>vgl.txt
>>"%destination%lpha.bat" ECHO if
"%%roofgo%%" == "9 " echo o.k. ^>vgl.txt
Die vier Zeilen sind zur Ermittlung eines Buchstabens. Der wird im
Gegensatz zum Buchstabenzählen nicht bei jedem Schleifendurchlauf (set eu1strang=%%eu1strang%%%%trang1%%)
addiert.
Also wird bei jedem Schleifendurchlauf die YZahl erhöht (:~0,1%,
:~0,2%...., :~0,5%..).
Es wird dann mit einer Positivliste gearbeitet:
>>"%destination%lpha.bat"
ECHO if "%%roofgo%%" == "1Leerzeichen"
echo o.k. ^>vgl.txt
In dieser Zeile wird abgefragt, ob eine 1 vorliegt. Das Leerzeichen
dürfen Sie nicht vergessen, deshalb wird es hier noch einmal als Wort
deutlich hingeschrieben - das ist der cmd geschuldet und Sie schreiben
natürlich nicht das Leerzeichen hin..
----
Einschub:
Für Profis: Das Leerzeichen entsteht durch den Eibau der
Variablen in der Vairable. Solche Gemeinheiten kriegen Sie leicht
heraus, wenn Sie mit ausezeichen in der Übungsbatch die cmd an
einem bestimmten Abschnitt einfrieren.
Einer der gemeinsten Bugs von der Microsoft Corporation ist übrigens
bei der Übernahme einer Zeile aus einem Texdokument ein nicht sehbares
Steuerzeichen.
bei set /p x=<password.txt wird
diess Steuerzeichen übernommen und kann dann im schlimsten Fall nur
durch einen for-Befehl wieder escaped werden - der Autor wies des
öfteren darauf hin. Manchmal hat der Autor den Eindruck, dass bewußt
solche Erschwernisse eingebaut worden sind, um Batchschreiber
auszubremsen...
Eine andere Möglichkeit in der Batch wäre es mit set /a vor roofgo die Zahl zu escapen (vom unsichtbaren Steuerzeichen zu befreien), dann würde das Leerzeichen entfallen und dort if "%%roofgo%%" == "1" echo o.k. stehen, aber dann könnten Sie nur noch Zahlen überprüfen - also vergessen Sie das!!!
Einschubende
----
Geht das nur mit Zahlen? Nein, natürlich auch mit Buchstaben und
überwiegend auch mit Sonderzeichen - testen Sie das mit der Batch!
Liegt eine 1 vor, dann wird ein Dokument geschaffen. Dieses Dokument
wird überprüft (if not exist
vgl.txt echo Ein unbekannter Buchstabe wurde verwendet >fehler.txt)
und bei nicht vorliegen des Dokumentes ein Fehlertext mit dem eben
genannten if Befehl erschaffen.
Beim nächsten Durchlauf liegt bereits das Dokument mit dem Fehlertext
vor. Ist noch ein Fehler vorhanden, so wird er nicht gezählt. Es geht nur
darum einen Fehler zu finden...
if exist fehler.txt start ""
"%windir%\system32\notepad.exe" "%destination%fehler.txt" ist
dann der Befehl zur Abfrage, ob ein Fehler.txt vorliegt.
War ein
Buchstabe außerhalb den Zahlen von 1-9 im Dokument, dann gibt es wieder
die Möglichkeit, z. B. mit einem goto - Befehl vor die Passworteingabe
zurückzugehen und eine Neueingabe zu veranlassen...
Ansonsten wird der del vgl.txt nach
jedem Durchlauf zerstört, damit beim nächsten Vergleich wieder kein
vgl.txt vorliegt und so der Trugschluss entstehen könnte, dass die
folgenden Buchstaben auch richtig sind...
Es lohnt sich die Länge mit einer Inhaltsprüfung zu kombinieren -
deshalb nur eine Batch...
Die Positivliste kann beliebig erweitert werden:
>>"%destination%lpha.bat" ECHO if
"%%roofgo%%" == "@ " echo o.k. ^>vgl.txt
(>>"%destination%lpha.bat" ECHO if
"%%roofgo%%" == "@Leerzeichen" echo o.k. ^>vgl.txt)
würde nun ein @ suchen...
Sie wollen lieber mit einer Negativliste arbeiiten?
Fast dasselbe Spiel, nur dass Sie diesmal die Zeichen aufführen, die
nicht vorkommen. Danach arbeiten Sie wie im Batchteil der Länge - naja,
ist auch nicht komplizierter.
Bei einem Negativeintrag liegt ja ein vgl.txt
vor. Der darf nun nicht mehr gelöscht werden, denn der Text
dokumentiert einen Fehler.
Also del vgl.txt löschen und schon
wird aus der Positivliste eine Negativliste, in der zur Zeit keine
Zahlen erlaubt wären...
Ach ja, der Ergebnissatz muss geändert werden : if not exist vgl.txt echo Ein
unbekanntes Zeichen außerhalb von 1 - 9 wurde verwendet >fehler.txt muss geändert werden in if exist vgl.txt.
Anmerkung für angehende Profis: Es ist auch nicht verkehrt eine Null
oder 1 in diese Texte zu schreiben (Wahrwert 1 und Unwahrwert 0.
Man kann dann leichter damit Arbeiten und mit set /p irgendeeinevariable<=vgl.txt das Ergebnis
impotieren - dann sollten Sie mit set /a neuebeliebige
Variable=%irgendeinevariable% Rechenoperationen durchführen können oder
zumindest bei anderer Verwendung daran denken, dass dorrt evtl. ein
Steuerzeichen nach der 1 steht, was bei weiteren EQU mit if Befehlen
dann beachtet werden muss...
Also wenn ein vgl. Dokument vorhanden ist, dann gab es einen Fehler...
Sie wollen die Fehler zählen? Am Ende des Schleifendurchgangs ist genug
Platz, um außerhalb der Hilfebatch einfach die Variable YZahl bei
vorliegen eines Fehlers z. B. in eine neue Variable oder ein
Textdokument zu schreiben...
Fazit
Die Batch bietet eine gute Grundlage, um mit wenigen Änderungen
Inhalt
und Länge eines Inputs oder eines Passworts zu überprüfen, egal ob
Positivliste, Negativliste oder nur die Länge des Inputwortes - das ist
eben auch mit einer Batch möglich...