Batch Password Generator?
Hey, ich bins mal wieder! ich wollte mal fragen ob es möglich wäre einen Passwort Generator zu bauen, das geht ja mit %random%, doch da hat man keine buchstaben. könnte ich trodzdem so etwas scripten? Danke im vorrauß! LG max
2 Antworten
heute habe ich nicht mehr viel Lust zu erklären:
@echo off
chcp 65001 >nu
setlocal enabledelayedexpansion
rem alle möglichen Zeichen
set "StringOfChars=_@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
rem Zeichen in StringOfChars...
set "countOfChars=64"
rem Länge von Key:20 (kann auch kürzer oder länger sein), bei 1.000.000 mio zufallsstrings gab es keine Duplikate
call :createKey Key 20
rem Key anzeigen
echo das ist ein 20 Zeichen langer Key:
echo %Key%
echo:
rem Länge von Key:128
call :createKey Key 128
echo das ist ein 20 Zeichen langer Key:
echo %Key%
pause
exit /b
:: ========== Unterprogramme ==========
:createKey %1= VariableName um den Key aufzunehmen %2=Länge des Keys
setlocal
rem generiere Key
for /l %%a in (1,1,%~2) do (
rem Zufallszahl zwischen 0 und (Anzahl der Zeichen im String)-1 würfeln
call :getNewRandom newRandom %countOfChars%
rem Zeichen Nummer ZufallsZahl aus %StringOfChars% ermitteln
call set "this.Char=%%StringOfChars:~!newRandom!,1%%"
rem Zeichen zu Variable key hinzufügen
set "this.Key=!this.Key!!this.Char!"
)
endlocal & set "%1=%this.Key%"
exit /b
:getNewRandom %1=VarName %2=RandomFactor
set /a "%1=!random! %% %2"
rem Dafür sorgen das nicht 2 mal die gleiche Zahl aufeinander folgt...
if "!%1!"=="!%1.old!" goto :getNewRandom
set "%1.old=!%1!"
exit /b
Die etwas ausgefeiltere Variante.
Eigentlich musst Du nur die Variable keyLength= anpassen. Neue Keys /Passwörter werden zur Datei keys.txt hinzugefügt...
@echo off
chcp 65001 >nul
setlocal enabledelayedexpansion
rem alle möglichen Zeichen
set "StringOfChars=_@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
rem Zeichen in StringOfChars zählen und in der variable countOfChars
call :getStringLength countOfChars "%StringOfChars%"
rem Länge von Key
set "keyLength=8"
set "outputFile=keys.txt"
:::::::::::::::: ein wenig Interaktivität ;p :::::::::::::
call :askSettings ||exit /b
echo ...erzeuge %numberOfKeys% Keys:
call :getTimeStamp loopStart
rem Zählschleife: führe %numberOfKeys% mal das Unterprogramm :createKey aus
for /l %%i in (1,1,%numberOfKeys%) do (
rem erzeuge Ergebnis in der Variable __Key
call :createKey __Key
rem Key anzeigen
echo !__Key! %%i
rem wenn in Datei gepeichert werden soll...
if "%save%"=="true" (
rem ...Key in Datei schreiben
echo !__Key!>>"%outputFile%"
) )
::::::::::::::: Ende der Schleife ::::::::::::::::::::::::::::::::::::::::::::::::::::
echo Es wurden %numberOfKeys% Keys erzeugt.
echo:
rem mit geschriebenen Daten arbeiten
if "%save%"=="true" (
if exist "%outputFile%" (
call :showSorted
call :findDuplcates
timeout 2 >nul
rem .txt-Datei mit Standard-Anwendung öffnen
start "" "%outputFile%"
) )
pause
exit /b
:::::::::::::::::::: Programm Ende :::::::::::::::::::::
:: ========== Unterprogramme ==========
:createKey %1= VariableName um den Key aufzunehmen
setlocal
rem generiere Key
for /l %%a in (1,1,%keyLength%) do (
rem Zufallszahl zwischen 0 und (Anzahl der Zeichen im String)-1 würfeln
call :getNewRandom newRandom %countOfChars%
rem Zeichen Nummer ZufallsZahl aus %StringOfChars% ermitteln
call set "this.Char=%%StringOfChars:~!newRandom!,1%%"
rem Zeichen zu Variable key hinzufügen
set "this.Key=!this.Key!!this.Char!"
)
endlocal & set "%1=%this.Key%"
exit /b
:::::: Abfragen
:askSettings
rem Abfrage wieviele Keys erzeugt werden sollen
for /l %%a in (1,1,3) do (
set /p "numberOfKeys=Wie viele Keys sollen generiert werden? :"
rem prüfen ob eine Zahl eingegeben wurde, wenn richtig Schleife abbrechen
call :isNumber !numberOfKeys! && goto :break
echo ...eine Zahl eingeben ^^!^^!^^!
)
echo:
echo 3 Mal keine Zahl eingegeben... o.O ich hau ab...
timeout 5 >nul
rem ... errorlevel 4712 setzen (sch*** egal ;p)
exit /b 4712
:break
if %numberOfKeys% equ 0 (
echo:
echo ...nichts zu tun...Tschuess
timeout 2 >nul
exit /b 99
)
rem Abfrage ob die erzeugten Keys in in eine Datei gespeichert werden sollen
choice /c JN /m "Sollen diese in die Datei "%outputFile%" gespeichert werden? "
rem wenn ja setze die Variable save=true
if %errorlevel% equ 1 (set "save=true")
exit /b 0
:::::: ende Abfragen
:showSorted
choice /c JN /m "Sortiert anzeigen? "
if !errorlevel! equ 1 (
echo:
type "%outputFile%"|sort|more
)
exit /b
:findDuplcates
choice /c JN /m "Duplikate suchen? "
if !errorlevel! equ 1 (
echo:
set "__D_Counter=0"
for /f "tokens=*" %%a in ('type "%outputFile%"^|sort') do (
if "!__last!"=="%%a" (
echo Dulikat gefunden...: %%a
set /a "__D_Counter+=1"
pause
)
set "__last=%%a"
)
echo !__D_Counter! Duplikate gefunden
)
exit /b
::-------------- Helperfunctions ---------------------------
:isNumber %1=sollte Zahl sein
rem wenn keine Zahl wird errorlevel
set /a "dummy=%1" 2>nul || exit /b 2 gesetzt
if "%dummy%"=="%1" exit /b 0
exit /b 1
:getStringLength %1=VarName %2="String"
rem länge eines String ermitteln
echo:%~2 >"%temp%\length_4_%1.tmp"
for %%f in ("%temp%\length_4_%1.tmp") do (set /a "%1=%%~zf-3" )
exit /b
:getNewRandom %1=VarName %2=RandomFactor
set /a "%1=!random! %% %2"
rem Dafür sorgen das nicht 2 mal die gleiche Zahl aufeinander folgt...
if "!%1!"=="!%1.old!" goto :getNewRandom
set "%1.old=!%1!"
exit /b
:getTimeStamp param: %1=VariableName [%2=length] default=15 (yymmddHHMMSS3ms)
for /f "skip=2 tokens=2,3 delims=,.+" %%a in ('wmic os get localdatetime /format:csv') do (
set "%~1=%%a%%b"
if "%~2"=="" (set "%~1=!%~1:~2,15!") else (set "%~1=!%~1:~2,%~2!")
)
exit /b
...Der Generator ist ein Überbleibsel aus einem älteren Projekt, desshalb verwende ich Key statt Passwort. Im Prinzip ist es Wurst wie man das Kind nennt. Hauptsache wirklich sehr Zufällig.
Du kannst ja mal 10000 von den Keys 8 Zeichen langen Keys erzeugen und schauen wieviel Duplikate es gibt.
Eine entsprechende Routine ist enthalten...
Wenn man nur ein einzelnes Passwort haben will und nicht geprüft werden soll, ob das Passwort schon mal erstellt wurde, kann man auch in Batch den Umweg über PowerShell nehmen:
powershell -ex bypass -c "[string]::Join('',{$r=[Random]::new();0..(Read-Host -P 'Länge')|%{[char]$r.Next(33,126)}}.Invoke())"
(PS: ich kann es leider nicht in cmd testen, weil der Windows Defender neuerdings meint, gleich Warnmeldungen per E-Mail wegen "suspicious powershell script" zu verschicken, wenn ich einen powershell-Befehl in cmd ausführe, aber im Prinzip sollte das so laufen)
Warum Dein Defender rebelliert kann ich nicht nachvollziehen. 🤔(da ist bei mir die Heuristik schon Zuviel gewöhnt?) ...könnte aber durchaus sein , das er sich am Scriptblock.Invoke() gestoßen hat. Scriptblöcke kann man auch zur Codeinjektion zur Laufzeit nutzen 😲 . Powershell ist da nicht ganz "ohne"!
#scriptinjection zur Laufzeit ...tippe mal get-random ein
$scriptBlock = [Scriptblock]::Create((Read-host -p 'enter Code:'))
$scriptBlock.Invoke()
Du hast es etwas zu "gut" gemeint. (Kanonen auf Spatzen)
- Für ein "commandlinescript" brauchst du keine Ex.Policy zu setzen.
- etwas weniger .Net und der Scriptblock (...und dessen .Invoke) wären überflüssig
- für Get-Random braucht man auch nicht explizit ein Random-Objekt initialisieren
- mit %-Zeichen in cmd sollte man behutsam Umgehen, diese kennzeichnen Variablen und müssten in einer Batch verdoppelt werden, Mit dem alias foreach umschifft man dies.
Ich denke mal mit Folgendem dürfte auch der Defender zufrieden sein:
powershell -c "(1..(Read-Host -P 'Laenge')|foreach{[char](Get-Random -min 33 -max 126)})-join ''"
mit Powershell 7 wird es noch billiger:
pwsh.exe -c "[char[]]( Get-Random -count (Read-Host -P 'Länge') -min 33 -max 126) -join ''"
...auf Speed braucht man bei beiden nicht zu schauen, da ist der Anlaufoverhead von PowerShell einfach zu gewaltig.
Hier das Ganze in Powershell (zigmal schneller)
randomKeys.ps1
$StringOfChars='_@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$KeyLength=8;
$KeyFile='Keys.txt';
do {$NumberOfKeys = $(read-host 'Wieviele neue Passwoerter sollen erzeugt werden?') -as [uint32] } until ($NumberOfKeys)
#bereits erzeugte Keys laden (um evtl. erzeugte Duplikate zu finden)
'Lade Keys aus Datei...'
$AllKeys = Get-Content $KeyFile -erroraction SilentlyContinue -readcount 0;
'{0} Keys aus Datei geladen' -f $AllKeys.count;
#wenn die gewünschte größe des Keys die Anzahl der verfügbaren Zeichen übersteigt, vervielfache den String
while ($KeyLength -gt $StringOfChars.length ){$StringOfChars+=$StringOfChars};
$current = Get-Date
$NewKeys += 1..$NumberOfKeys|foreach{
#erzeuge Zufallsstring
$Key = -join([System.Text.Encoding]::Default.GetBytes($StringOfChars) |Get-Random -Count $KeyLength| %{[char]$_});
#Fortschritt anzeigen, (aber nicht an Sammelvariable übergeben)
#wenn du die folgende Zeile entfernst/auskommentierst verdreifacht sich die Geschwindigkeit!
Write-Host ('{0}' -f $Key,$_) -fo green -n;Write-Host (' {0}' -f $_)
#Key an Sammelvariable übergeben
$Key;
}
$end= Get-Date
Write-Host('Dauer: {0} Sekunden fuer {1} Keys' -f ((New-TimeSpan -Start $current -End $end).TotalSeconds),$NewKeys.count) -fo blue;
'{0} neue Keys ereugt' -f $NewKeys.count
#neue Keys zu bestehenden hinzufügen
$AllKeys += $NewKeys
'Insgesammt {0} Keys vorhanden' -f $AllKeys.count
'suche Duplikate...'
$CleanedKeys = $AllKeys| sort |%{$old=$Null;$DuplicateCount=0;}{
if ($_ -eq $old){
Write-Host $_ -fo Red;
$DuplicateCount+=1;
} else {$_};
$old=$_;
}
'{0} Duplikate entfernt' -f ($DuplicateCount)
'schreibe {0} Keys in Datei' -f $CleanedKeys.count
#superschnelle Methode um ein riesige Powershellarrays in einem Rutsch in eien Datei zu schreiben
$StreamWriter = New-Object System.IO.StreamWriter($KeyFile)
#wandle ein Array in einen String (füge als Trennzeichen eien Zeilenvorschub ein) ...und schreibe diesen in die Datei
$StreamWriter.write(($CleanedKeys -join [Environment]::NewLine))
$StreamWriter.close()
'fertig...'
pause
Da sich Powershell nur über das Kontextmenü starten lässt, das ganze als Hybrdbatch:
randomKeys.cmd
<# : begin batchpart (don't change this line)
@echo off
rem run appended Powershell/C#-script
start "" powershell "iex (${%~f0}|out-string)"
exit /b
::end batchpart (don't change this line)#>
$StringOfChars='_@ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$KeyLength=8;
$KeyFile='Keys.txt';
do {$NumberOfKeys = $(read-host 'Wieviele neue Passwoerter sollen erzeugt werden?') -as [uint32] } until ($NumberOfKeys)
'Lade Keys aus Datei...'
$AllKeys = Get-Content $KeyFile -erroraction SilentlyContinue -readcount 0;
'{0} Keys aus Datei geladen' -f $AllKeys.count;
while ($KeyLength -gt $StringOfChars.length ){$StringOfChars+=$StringOfChars};
$current = Get-Date
$NewKeys += 1..$NumberOfKeys|foreach{
$Key = -join([System.Text.Encoding]::Default.GetBytes($StringOfChars) |Get-Random -Count $KeyLength| %{[char]$_});
#wenn du die folgende Zeile entfernst/auskommentierst verdreifacht sich die Geschwindigkeit!
Write-Host ('{0}' -f $Key,$_) -fo green -n;Write-Host (' {0}' -f $_);
$Key;
}
$end= Get-Date
Write-Host('Dauer: {0} Sekunden fuer {1} Keys' -f ((New-TimeSpan -Start $current -End $end).TotalSeconds),$NewKeys.count) -fo blue;
'{0} neue Keys ereugt' -f $NewKeys.count
$AllKeys += $NewKeys
'Insgesammt {0} Keys vorhanden' -f $AllKeys.count
'suche Duplikate...'
$CleanedKeys = $AllKeys| sort |%{$old=$Null;$DuplicateCount=0;}{
if ($_ -eq $old){
Write-Host $_ -fo Red;
$DuplicateCount+=1;
} else {$_};
$old=$_;
}
'{0} Duplikate entfernt' -f ($DuplicateCount)
'schreibe {0} Keys in Datei' -f $CleanedKeys.count
$StreamWriter = New-Object System.IO.StreamWriter($KeyFile)
$StreamWriter.write(($CleanedKeys -join [Environment]::NewLine))
$StreamWriter.close()
'fertig...'
pause
10000 Keys in 13 Sekunden (@ 4,3GHz)
4 Sekunden, wenn die Zeile:
Write-Host ('{0}' -f $Key,$_) -fo green -n;Write-Host (' {0}' -f $_)
...entfernt wird.
Also theoretisch auch wenn Zufall nicht wirklich existiert man kann ja eigentlich den Zufall berechnen aber du könntest nur ein bsp auch wenn ich nicht verstehe warum batch und nicht Python oder so.
Du könntest ganz einfach mit random eine Zahl raus picken indem du sagen wir in der variabel die du setzen kannst gewisse Zahlen zu ersetzen
Super_passwort = %Random%%Random%%Random%
Set Super_passwort=%Super_passwort:eine zahl=Buchstabe%
Rem so könntest du quasi gewisse zufallszahlen ersetzen wie lange du das jetzt ziehst und welchen Buchstaben du durch welche Zahl ersetzt bleibt dir überlassen natürlich wird es da schnell an seinem Limit kommen aber es ist ja nur ein batch script
Hut ab, dass du sowas in Batch gebaut kriegst