batch file - programacion - ¿Puedo enmascarar un texto de entrada en un archivo bat?
lenguaje batch (14)
Este puede ser un tema más antiguo, pero si está usando Windows Vista o 7, tengo una solución que funcionará muy bien. Hice un video de esto aquí: http://www.youtube.com/watch?v=mk8uAa6PIFM
Pastebin para el archivo por lotes está aquí
Estoy escribiendo un archivo por lotes para ejecutar algunos otros programas. En este caso, necesito pedir una contraseña. ¿Tengo alguna forma de enmascarar el texto de entrada? No necesito imprimir caracteres ******* en lugar de ingresar caracteres. Comportamiento de solicitud de contraseña de Linux (No imprimir nada mientras se escribe) es suficiente.
@echo off
SET /P variable=Password :
echo %variable%
Pause
Esto leerá la entrada pero no puedo enmascarar el texto usando este enfoque.
Hasta XP y Server 2003, puede hacer uso de otra herramienta incluida (VBScript): las siguientes dos secuencias de comandos hacen el trabajo que desea.
Primero, getpwd.cmd
:
@echo off
<nul: set /p passwd=Password:
for /f "delims=" %%i in (''cscript /nologo getpwd.vbs'') do set passwd=%%i
echo.
Entonces, getpwd.vbs
:
Set oScriptPW = CreateObject("ScriptPW.Password")
strPassword = oScriptPW.GetPassword()
Wscript.StdOut.WriteLine strPassword
El getpwd.vbs
simplemente usa el objeto de contraseña para ingresar la contraseña del usuario y luego imprimirla a la salida estándar (el siguiente párrafo explicará por qué eso no aparece en el terminal).
El getpwd.cmd
comando getpwd.cmd
es un poco más complicado, pero básicamente funciona de la siguiente manera.
El efecto del comando "<nul: set /p passwd=Password: "
es generar el prompt sin ningún carácter de nueva línea al final - es una forma furtiva de emular el comando "echo -n"
del shell bash
. Establece passwd
a una cadena vacía como un efecto secundario irrelevante y no espera la entrada ya que está tomando su entrada desde el nul:
dispositivo.
La "for /f "delims=" %%i in (''cscript /nologo getpwd.vbs'') do set passwd=%%i"
es el más complicado. Ejecuta el VBScript sin "publicidad" de Microsoft, de modo que la única salida de línea es la contraseña (del VBscript "Wscript.StdOut.WriteLine strPassword"
.
Se requiere el ajuste de los delimitadores para capturar una línea de entrada completa con espacios, de lo contrario solo obtendrá la primera palabra. El bit "for ... do set ..."
establece que passwd
es la salida de contraseña real de VBScript.
Luego hacemos eco de una línea en blanco (para terminar la línea "Password: "
) y la contraseña estará en la variable de entorno passwd
después de que se haya ejecutado el código.
Ahora, como se mencionó, scriptpw.dll
está disponible solo hasta XP / 2003. Para rectificar esto, simplemente copie el archivo scriptpw.dll
de la carpeta Windows/System32
de un sistema XP / 2003 a la Winnt/System32
o Windows/System32
en su propio sistema. Una vez que se ha copiado el archivo DLL, deberá registrarlo ejecutando:
regsvr32 scriptpw.dll
Para registrar correctamente la DLL en Vista y más adelante, necesitará privilegios de administrador. No he examinado la legalidad de tal movimiento, así que lector de cuevas.
Si no está demasiado interesado en tratar de rastrear y registrar archivos DLL más antiguos (por conveniencia o por razones legales), hay otra manera. Las versiones posteriores de Windows (las que no tienen la DLL requerida) deben tener Powershell disponible para usted.
Y, de hecho, realmente debería considerar actualizar sus scripts para usarlo completamente, ya que es un lenguaje de scripting mucho más capaz que cmd.exe
. Sin embargo, si desea mantener la mayor parte del código como scripts cmd.exe
(por ejemplo, si tiene muchos códigos que no desea convertir), puede usar el mismo truco.
Primero, modifique el script cmd
para que llame a Powershell en lugar de a CScript:
@echo off
for /f "delims=" %%i in (''powershell -file getpwd.ps1'') do set passwd=%%i
La secuencia de comandos de Powershell es igualmente simple:
$password = Read-Host "Enter password" -AsSecureString
$password = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($password)
$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto($password)
echo $password
aunque con un poco de clasificación para obtener el texto de la contraseña real.
Recuerde que, para ejecutar scripts de Powershell locales sin firmar en su máquina, es posible que deba modificar la política de ejecución desde el valor predeterminado (draconiano, aunque muy seguro), con algo como:
set-executionpolicy remotesigned
desde el interior de Powershell.
Leí todas las soluciones torpes en la red sobre cómo enmascarar contraseñas en un archivo por lotes, las de usar una solución hide.com e incluso las que hacen que el texto y el fondo sean del mismo color. La solución hide.com funciona decente, no es muy segura y no funciona en Windows de 64 bits. Entonces, de todos modos, usando las utilidades 100% de Microsoft, ¡hay una manera!
Primero, déjame explicarte mi uso. Tengo alrededor de 20 estaciones de trabajo que inician sesión automáticamente en Windows. Tienen un atajo en su escritorio, para una aplicación clínica. Las máquinas están bloqueadas, no pueden hacer clic derecho, no pueden hacer otra cosa que acceder a un acceso directo en su escritorio. En ocasiones, es necesario que un técnico active algunas aplicaciones de depuración, explore el explorador de Windows y observe los archivos de registro sin cerrar la cuenta de usuario de autolog.
Entonces esto es lo que hice.
Hazlo como quieras, pero pongo mis dos archivos por lotes en un recurso compartido de red al que tiene acceso la computadora bloqueada.
Mi solución utiliza 1 componente principal de Windows - runas. Ponga un atajo en los clientes al runas.bat que está a punto de crear. FYI, en mis clientes cambié el nombre del atajo para una mejor visualización y cambié el ícono.
Tendrá que crear dos archivos por lotes.
Llamé a los archivos por lotes runas.bat y Debug Support.bat
runas.bat contiene el siguiente código:
cls
@echo off
TITLE CHECK CREDENTIALS
goto menu
:menu
cls
echo.
echo ....................................
echo ~Written by Cajun Wonder 4/1/2010~
echo ....................................
echo.
@set /p un=What is your domain username?
if "%un%"=="PUT-YOUR-DOMAIN-USERNAME-HERE" goto debugsupport
if not "%un%"=="PUT-YOUR-DOMAIN-USERNAME-HERE" goto noaccess
echo.
:debugsupport
"%SYSTEMROOT%/system32/runas" /netonly /user:PUT-YOUR-DOMAIN-NAME-HERE/%un% "//PUT-YOUR-NETWORK-SHARE-PATH-HERE/Debug Support.bat"
@echo ACCESS GRANTED! LAUNCHING THE DEBUG UTILITIES....
@ping -n 4 127.0.0.1 > NUL
goto quit
:noaccess
cls
@echo.
@echo.
@echo.
@echo.
@echo ///////////////////////////////////////
@echo // //
@echo // Insufficient privileges //
@echo // //
@echo // Call Cajun Wonder //
@echo // //
@echo // At //
@echo // //
@echo // 555-555-5555 //
@echo // //
@echo ////////////////////////////////////////
@ping -n 4 127.0.0.1 > NUL
goto quit
@pause
:quit
@exit
Puede agregar tantos si "% un%" y si no "% un%" para todos los usuarios a los que desea dar acceso. El @ping es mi manera de hacer un temporizador de segundos.
Así que eso cuida el primer archivo por lotes, bastante simple ¿eh?
Aquí está el código para Debug Support.bat:
cls
@echo off
TITLE SUPPORT UTILITIES
goto menu
:menu
cls
@echo %username%
echo.
echo .....................................
echo ~Written by Cajun Wonder 4/1/2010~
echo .....................................
echo.
echo What do you want to do?
echo.
echo [1] Launch notepad
echo.
:choice
set /P C=[Option]?
if "%C%"=="1" goto notepad
goto choice
:notepad
echo.
@echo starting notepad....
@ping -n 3 127.0.0.1 > NUL
start notepad
cls
goto menu
No soy un codificador y realmente comencé a utilizar scripts por lotes hace aproximadamente un año, ¡y esta ronda que descubrí para enmascarar una contraseña en un archivo por lotes es bastante impresionante!
¡Espero escuchar que alguien que no sea yo pueda sacarle provecho!
Otra alternativa son mis herramientas de línea de comandos EditV32 (x86) o EditV64 (x64). Por ejemplo:
editv32 -m -p "Password: " PWD
-m significa "entrada enmascarada" y -p es el aviso. La entrada del usuario se almacena en la variable de entorno PWD. Puedes obtenerlo aqui:
Probablemente solo lo haga:
..
echo Before you enter your password, make sure no-one is looking!
set /P password=Password:
cls
echo Thanks, got that.
..
Entonces, recibe un aviso, luego la pantalla se borra después de que se ingresa.
Tenga en cuenta que la contraseña introducida se almacenará en el historial de CMD si el archivo por lotes se ejecuta desde un símbolo del sistema (Gracias @Mark K Cowan ).
Si eso no fuera lo suficientemente bueno, cambiaría a Python o escribiría un ejecutable en lugar de un script.
Sé que ninguno de estos son soutions perfectos, pero tal vez uno es lo suficientemente bueno para ti :)
Puede usar la subrutina ReadFormattedLine para todo tipo de entrada formateada. Por ejemplo, el siguiente comando lee una contraseña de 8 caracteres, muestra asteriscos en la pantalla y continúa automáticamente sin necesidad de presionar Enter:
call :ReadFormattedLine password="********" /M "Enter password (8 chars): "
Esta subrutina está escrita en lote puro por lo que no requiere ningún programa adicional, y permite varias operaciones de entrada formateadas, como leer solo números, convertir letras a mayúsculas, etc. Puede descargar la subrutina ReadFormattedLine desde Leer una línea con un formato específico .
Sí, tengo 4 años de retraso.
Pero encontré una forma de hacerlo en una línea sin tener que crear una secuencia de comandos externa; llamando comandos de powershell desde un archivo por lotes.
Gracias a TessellatingHeckler, sin generar un archivo de texto (configuré el comando powershell en una variable, porque es bastante desordenado en una línea larga dentro de un ciclo for).
@echo off
set "psCommand=powershell -Command "$pword = read-host ''Enter Password'' -AsSecureString ; ^
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword); ^
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR)""
for /f "usebackq delims=" %%p in (`%psCommand%`) do set password=%%p
echo %password%
Originalmente lo escribí para enviarlo a un archivo de texto, luego lo leí de ese archivo de texto. Pero el método anterior es mejor. En una línea extremadamente larga, casi incomprensible:
@echo off
powershell -Command $pword = read-host "Enter password" -AsSecureString ; $BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt & set /p password=<.tmp.txt & del .tmp.txt
echo %password%
Voy a analizar esto, puedes dividirlo en unas pocas líneas con cuidado ^
, que es mucho mejor ...
@echo off
powershell -Command $pword = read-host "Enter password" -AsSecureString ; ^
$BSTR=[System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($pword) ; ^
[System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) > .tmp.txt
set /p password=<.tmp.txt & del .tmp.txt
echo %password%
Este artículo explica qué están haciendo los comandos de PowerShell; esencialmente obtiene entrada utilizando Read-Host -AsSecureString
- las siguientes dos líneas convierten esa cadena segura nuevamente en texto plano, la salida (contraseña de texto plano) se envía a un archivo de texto usando >.tmp.txt
. Ese archivo se lee en una variable y se elimina.
Si la falta de código fuente te molesta, tengo otra alternativa.
@echo off
for /f "delims=" %%p in (''ReadLine -h -p "Enter password: "'') do set PWD=%%p
echo You entered: %PWD%
Puede obtenerlo en ReadLine.exe . El código fuente está incluido.
Si tiene Python instalado, puede usar:
for /f "delims=" %%A in (''python -c "import getpass; print(getpass.getpass(''Enter the CVS password: ''));"'') do @set CVSPASS=%%A
echo PASS: %CVSPASS%
La salida:
Enter the CVS password:
PASS: 123
Utilicé la solución anterior de Blorgbeard, que en realidad es genial en mi opinión. Luego lo mejoré de la siguiente manera:
- Google para ansicon
- Descargue el archivo zip y el archivo de texto de muestra.
- Instalar (eso significa copiar 2 archivos en system32)
Úselo así:
@echo off
ansicon -p
set /p pwd=Password:ESC[0;37;47m
echo ESC[0m
Esto cambia la consola a gris en gris para la entrada de su contraseña y vuelve a cambiar cuando haya terminado. El ESC debería ser en realidad un carácter no imprimible, que puede copiar desde el archivo de texto de muestra descargado (aparece como una flecha izquierda en el Bloc de notas) en su archivo por lotes. Puede usar el archivo de texto de muestra para buscar los códigos para todas las combinaciones de colores.
Si no es administrador de la máquina, probablemente pueda instalar los archivos en un directorio que no sea del sistema, luego deberá agregar el directorio a la RUTA en su secuencia de comandos antes de llamar al programa y usar las secuencias de escape. Incluso podría ser el directorio actual, si necesita un paquete distribuible de solo unos pocos archivos.
crea un archivo por lotes que llama al necesario para los caracteres invisibles y luego crea un acceso directo para el archivo por lotes al que se llama.
botón derecho del ratón
propiedades
colores
texto == negro
fondo == negro
aplicar
De acuerdo
espero que así te ayude !!!!!!!!
1. Solución de lote puro que (ab) utiliza el comando XCOPY
y sus conmutadores /P /L
se encuentran here ( here encontrar algunas mejoras):
:: Hidden.cmd
::Tom Lavedas, 02/05/2013, 02/20/2013
::Carlos, 02/22/2013
::https://groups.google.com/forum/#!topic/alt.msdos.batch.nt/f7mb_f99lYI
@Echo Off
:HInput
SetLocal EnableExtensions EnableDelayedExpansion
Set "FILE=%Temp%./T"
Set "FILE=./T"
Keys List >"%File%"
Set /P "=Hidden text ending with Ctrl-C?: " <Nul
Echo.
Set "HInput="
:HInput_
For /F "tokens=1* delims=?" %%A In (
''"Xcopy /P /L "%FILE%" "%FILE%" 2>Nul"''
) Do (
Set "Text=%%B"
If Defined Text (
Set "Char=!Text:~1,1!"
Set "Intro=1"
For /F delims^=^ eol^= %%Z in ("!Char!") Do Set "Intro=0"
Rem If press Intro
If 1 Equ !Intro! Goto :HInput#
Set "HInput=!HInput!!Char!"
)
)
Goto :HInput_
:HInput#
Echo(!HInput!
Goto :Eof
1.2 Otra forma basada en reemplazar el comando
@Echo Off
SetLocal EnableExtensions EnableDelayedExpansion
Set /P "=Enter a Password:" < Nul
Call :PasswordInput
Echo(Your input was:!Line!
Goto :Eof
:PasswordInput
::Author: Carlos Montiers Aguilera
::Last updated: 20150401. Created: 20150401.
::Set in variable Line a input password
For /F skip^=1^ delims^=^ eol^= %%# in (
''"Echo(|Replace.exe "%~f0" . /U /W"'') Do Set "CR=%%#"
For /F %%# In (
''"Prompt $H &For %%_ In (_) Do Rem"'') Do Set "BS=%%#"
Set "Line="
:_PasswordInput_Kbd
Set "CHR=" & For /F skip^=1^ delims^=^ eol^= %%# in (
''Replace.exe "%~f0" . /U /W'') Do Set "CHR=%%#"
If !CHR!==!CR! Echo(&Goto :Eof
If !CHR!==!BS! (If Defined Line (Set /P "=!BS! !BS!" <Nul
Set "Line=!Line:~0,-1!"
)
) Else (Set /P "=*" <Nul
If !CHR!==! (Set "Line=!Line!^!"
) Else Set "Line=!Line!!CHR!"
)
Goto :_PasswordInput_Kbd
2. Usuario de contraseñas que usa una ventana emergente HTA . Este es un archivo hybrit .bat / jscript / mshta y debe guardarse como .bat :
<!-- :
:: PasswordSubmitter.bat
@echo off
for /f "tokens=* delims=" %%p in (''mshta.exe "%~f0"'') do (
set "pass=%%p"
)
echo your password is %pass%
exit /b
-->
<html>
<head><title>Password submitter</title></head>
<body>
<script language=''javascript'' >
window.resizeTo(300,150);
function entperPressed(e){
if (e.keyCode == 13) {
pipePass();
}
}
function pipePass() {
var pass=document.getElementById(''pass'').value;
var fso= new ActiveXObject(''Scripting.FileSystemObject'').GetStandardStream(1);
close(fso.Write(pass));
}
</script>
<input type=''password'' name=''pass'' size=''15'' onkeypress="return entperPressed(event)" ></input>
<hr>
<button onclick=''pipePass()''>Submit</button>
</body>
</html>
3. Un híbrido de .NET autocompuesto . Una vez más debe guardarse como .bat
. En diferencia con otras soluciones, creará / compilará un pequeño archivo .exe al que se llamará (si lo desea, puede eliminarlo). También requiere .NET Framework instalado, pero eso no es un problema:
@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal enableDelayedExpansion
for /f "tokens=* delims=" %%v in (''dir /b /s /a:-d /o:-n "%SystemRoot%/Microsoft.NET/Framework/*jsc.exe"'') do (
set "jsc=%%v"
)
if not exist "%~n0.exe" (
"%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)
for /f "tokens=* delims=" %%p in (''"%~n0.exe"'') do (
set "pass=%%p"
)
echo your password is !pass!
endlocal & exit /b %errorlevel%
*/
import System;
var pwd = "";
var key;
Console.Error.Write("Enter password: ");
do {
key = Console.ReadKey(true);
if ( (key.KeyChar.ToString().charCodeAt(0)) >= 20 && (key.KeyChar.ToString().charCodeAt(0) <= 126) ) {
pwd=pwd+(key.KeyChar.ToString());
Console.Error.Write("*");
}
if ( key.Key == ConsoleKey.Backspace && pwd.Length > 0 ) {
pwd=pwd.Remove(pwd.Length-1);
Console.Error.Write("/b /b");
}
} while (key.Key != ConsoleKey.Enter);
Console.Error.WriteLine();
Console.WriteLine(pwd);
ACTUALIZAR:
Agregué dos métodos nuevos que, en lugar de utilizar cls para ocultar la entrada, crean una nueva ventana emergente con una sola línea.
Los inconvenientes son que un método (método 2) deja basura en el registro - "Si se ejecuta sin los derechos adecuados", y el otro (método tres) agrega algo de basura al guión. Huelga decir que se puede escribir fácilmente en cualquier archivo tmp y eliminar, simplemente traté de encontrar una alternativa.
Limitación: la contraseña solo puede ser alfanumérica, ¡no hay otros caracteres!
@echo off
if "%1"=="method%choice%" goto :method%choice%
::::::::::::::::::
::Your code here::
::::::::::::::::::
cls
echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
echo :::: Batch script to prompt for password! :::
echo :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:choice
echo.
echo 1. First method
echo.
echo 2. Second method
echo.
echo 3. Third method
echo.
set/p choice=Choose a method:
if "%choice%" gtr "3" echo. & echo invalid option & echo. & pause & goto choice
call :vars
set options= %num%%smAlph%%cpAlph%
set pwdLen=6
if "%choice%" == "1" (
set /p=Password: <nul
for /l %%i in (1,1,%pwdLen%) do call :password
) else (
start /wait cmd /c call "%~f0" method%choice%
)
call :result%choice%
::just to see if it worked!
echo.
echo The Password you entered is: "%pwd%"&pause>nul
::::::::::::::::::
::More code here::
::::::::::::::::::
exit /b
:vars
set num=1234567890
set smAlph=abcdefghijklmnopqrstuvwxyz
set cpAlph=ABCDEFGHIJKLMNOPQRSTUVWXYZ
set pwd=
goto :EOF
:method2
call :popUp
setx result %pwd% >nul
goto :EOF
:method3
call :popUp
>> "%~f0" echo.
>> "%~f0" echo :result%choice%
>> "%~f0" echo set pwd=%pwd%
goto :EOF
:popUp
title Password
mode con lines=1 cols=30
color 5a
set /p=Password: <nul
for /l %%i in (1,1,%pwdLen%) do call :password
goto :EOF
:password
:: If you don''t want case sensative remove "/cs" but remember to remove %cpAlph% from the %options%
choice /c %options% /n /cs >nul
call SET pwd=%pwd%%%options:~%errorlevel%,1%%
set /p =*<nul
GOTO :EOF
:result2
for /f "tokens=3" %%a in (''reg query hkcu/environment /v result'') do set pwd=%%a
setx result "" >nul
reg delete hkcu/environment /v result /f >nul 2>&1
:result1
goto :EOF
::You can delete from here whenever you want.
Actualización: descubrí que la publicación de Sachadee es perfecta y acabo de agregarle mi peculiaridad "emergente".
@Echo Off
SetLocal EnableDelayedExpansion
if "%1"==":HInput" goto :HInput
set r=r%random%
start /wait cmd /c call "%~f0" :HInput
For /f "tokens=2,13 delims=, " %%a in (
''tasklist /v /fo csv /fi "imagename eq cmd.exe"
^|findstr /v "Windows//system32//cmd.exe"
^|findstr "set /p=%r%"''
) do (
set pid=%%a
set Line=%%b
set Line=!Line:%r%=!
set Line=!Line:~,-2!
)
taskkill /pid %pid:"=%>nul
goto :HIEnd
:HInput
SetLocal DisableDelayedExpansion
title Password
mode con lines=2 cols=30
Echo Enter your Code :
Set "Line="
For /F %%# In (
''"Prompt;$H&For %%# in (1) Do Rem"''
) Do Set "BS=%%#"
:HILoop
Set "Key="
For /F "delims=" %%# In (
''Xcopy /W "%~f0" "%~f0" 2^>Nul''
) Do If Not Defined Key Set "Key=%%#"
Set "Key=%Key:~-1%"
SetLocal EnableDelayedExpansion
If Not Defined Key start /min cmd /k mode con lines=1 cols=14 ^&set/p %r%!Line!=&exit
If %BS%==^%Key% (Set /P "=%BS% %BS%" <Nul
Set "Key="
If Defined Line Set "Line=!Line:~0,-1!"
) Else Set /P "=*" <Nul
If Not Defined Line (EndLocal &Set "Line=%Key%"
) Else For /F delims^=^ eol^= %%# In (
"!Line!") Do EndLocal &Set "Line=%%#%Key%"
Goto :HILoop
:HIEnd
Echo(
Echo Your code is : "!Line!"
Pause
Goto :Eof
@echo off
color 0f
MODE CON COLS=132 LINES=50
:start
cls
choice /C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.# /N /CS /M Please enter your password to continue. (Valid characters include all letters, numbers, and ! ? .) Press # to submit:
SET ecode=%ERRORLEVEL%
IF %ecode% EQU 66 goto submit
IF %ecode% EQU 1 SET out=A
IF %ecode% EQU 2 SET out=B
IF %ecode% EQU 3 SET out=C
IF %ecode% EQU 4 SET out=D
IF %ecode% EQU 5 SET out=E
IF %ecode% EQU 6 SET out=F
IF %ecode% EQU 7 SET out=G
IF %ecode% EQU 8 SET out=H
IF %ecode% EQU 9 SET out=I
IF %ecode% EQU 10 SET out=J
IF %ecode% EQU 11 SET out=K
IF %ecode% EQU 12 SET out=L
IF %ecode% EQU 13 SET out=M
IF %ecode% EQU 14 SET out=N
IF %ecode% EQU 15 SET out=O
IF %ecode% EQU 16 SET out=P
IF %ecode% EQU 17 SET out=Q
IF %ecode% EQU 18 SET out=R
IF %ecode% EQU 19 SET out=S
IF %ecode% EQU 20 SET out=T
IF %ecode% EQU 21 SET out=U
IF %ecode% EQU 22 SET out=V
IF %ecode% EQU 23 SET out=W
IF %ecode% EQU 24 SET out=X
IF %ecode% EQU 25 SET out=Y
IF %ecode% EQU 26 SET out=Z
IF %ecode% EQU 27 SET out=a
IF %ecode% EQU 28 SET out=b
IF %ecode% EQU 29 SET out=c
IF %ecode% EQU 30 SET out=d
IF %ecode% EQU 31 SET out=e
IF %ecode% EQU 32 SET out=f
IF %ecode% EQU 33 SET out=g
IF %ecode% EQU 34 SET out=h
IF %ecode% EQU 35 SET out=i
IF %ecode% EQU 36 SET out=j
IF %ecode% EQU 37 SET out=k
IF %ecode% EQU 38 SET out=l
IF %ecode% EQU 39 SET out=m
IF %ecode% EQU 40 SET out=n
IF %ecode% EQU 41 SET out=o
IF %ecode% EQU 42 SET out=p
IF %ecode% EQU 43 SET out=q
IF %ecode% EQU 44 SET out=r
IF %ecode% EQU 45 SET out=s
IF %ecode% EQU 46 SET out=t
IF %ecode% EQU 47 SET out=u
IF %ecode% EQU 48 SET out=v
IF %ecode% EQU 49 SET out=w
IF %ecode% EQU 50 SET out=x
IF %ecode% EQU 51 SET out=y
IF %ecode% EQU 52 SET out=z
IF %ecode% EQU 53 SET out=0
IF %ecode% EQU 54 SET out=1
IF %ecode% EQU 55 SET out=2
IF %ecode% EQU 56 SET out=3
IF %ecode% EQU 57 SET out=4
IF %ecode% EQU 58 SET out=5
IF %ecode% EQU 59 SET out=6
IF %ecode% EQU 60 SET out=7
IF %ecode% EQU 61 SET out=8
IF %ecode% EQU 62 SET out=9
IF %ecode% EQU 63 SET out=!
IF %ecode% EQU 64 SET out=?
IF %ecode% EQU 65 SET out=.
SET code=%out%
SET show=*
:loop
cls
choice /C ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?.# /N /CS /M Please enter your password to continue. (Valid characters include all letters, numbers, and ! ? .) Press # to submit: %code%
SET ecode=%ERRORLEVEL%
IF %ecode% EQU 66 goto submit
IF %ecode% EQU 1 SET out=A
IF %ecode% EQU 2 SET out=B
IF %ecode% EQU 3 SET out=C
IF %ecode% EQU 4 SET out=D
IF %ecode% EQU 5 SET out=E
IF %ecode% EQU 6 SET out=F
IF %ecode% EQU 7 SET out=G
IF %ecode% EQU 8 SET out=H
IF %ecode% EQU 9 SET out=I
IF %ecode% EQU 10 SET out=J
IF %ecode% EQU 11 SET out=K
IF %ecode% EQU 12 SET out=L
IF %ecode% EQU 13 SET out=M
IF %ecode% EQU 14 SET out=N
IF %ecode% EQU 15 SET out=O
IF %ecode% EQU 16 SET out=P
IF %ecode% EQU 17 SET out=Q
IF %ecode% EQU 18 SET out=R
IF %ecode% EQU 19 SET out=S
IF %ecode% EQU 20 SET out=T
IF %ecode% EQU 21 SET out=U
IF %ecode% EQU 22 SET out=V
IF %ecode% EQU 23 SET out=W
IF %ecode% EQU 24 SET out=X
IF %ecode% EQU 25 SET out=Y
IF %ecode% EQU 26 SET out=Z
IF %ecode% EQU 27 SET out=a
IF %ecode% EQU 28 SET out=b
IF %ecode% EQU 29 SET out=c
IF %ecode% EQU 30 SET out=d
IF %ecode% EQU 31 SET out=e
IF %ecode% EQU 32 SET out=f
IF %ecode% EQU 33 SET out=g
IF %ecode% EQU 34 SET out=h
IF %ecode% EQU 35 SET out=i
IF %ecode% EQU 36 SET out=j
IF %ecode% EQU 37 SET out=k
IF %ecode% EQU 38 SET out=l
IF %ecode% EQU 39 SET out=m
IF %ecode% EQU 40 SET out=n
IF %ecode% EQU 41 SET out=o
IF %ecode% EQU 42 SET out=p
IF %ecode% EQU 43 SET out=q
IF %ecode% EQU 44 SET out=r
IF %ecode% EQU 45 SET out=s
IF %ecode% EQU 46 SET out=t
IF %ecode% EQU 47 SET out=u
IF %ecode% EQU 48 SET out=v
IF %ecode% EQU 49 SET out=w
IF %ecode% EQU 50 SET out=x
IF %ecode% EQU 51 SET out=y
IF %ecode% EQU 52 SET out=z
IF %ecode% EQU 53 SET out=0
IF %ecode% EQU 54 SET out=1
IF %ecode% EQU 55 SET out=2
IF %ecode% EQU 56 SET out=3
IF %ecode% EQU 57 SET out=4
IF %ecode% EQU 58 SET out=5
IF %ecode% EQU 59 SET out=6
IF %ecode% EQU 60 SET out=7
IF %ecode% EQU 61 SET out=8
IF %ecode% EQU 62 SET out=9
IF %ecode% EQU 63 SET out=!
IF %ecode% EQU 64 SET out=?
IF %ecode% EQU 65 SET out=.
SET code=%code%%out%
SET show=%show%*
goto loop
:submit
cls
SET password=%code%
IF %password% EQU 0cZrocks! SET result=1
IF ELSE SET result=2
IF %result% EQU 1 echo password correct
IF %result% EQU 2 echo password incorrect
timeout /T 2 /NOBREAK >nul
cls
IF %result% EQU 1 goto end
IF ELSE goto start
:end