En el post de hoy vamos a leer una cadena usando C (compatible con C++) pero no vamos a mostrarla, simplemente vamos a mostrar asteriscos o cualquier otro carácter mientras el usuario escribe.

Esto será hecho en C con MinGW en Windows pero lo he probado igual con Dev-C++. Al final tendremos un programa que va a solicitar una contraseña, no la va a mostrar y mostrará asteriscos en su lugar.

Pequeña nota de seguridad

Ya no deberíamos usar C para cosas de seguridad. Sí, sé que varias cosas están programadas con C (librerías, paquetes, núcleos de sistemas operativos) y que si lo usamos bien no habrá problema, pero ya no es recomendable.

Yo hago este tutorial por si tu profesor quiere enseñarte las bases y hacerte sufrir pensando en el algoritmo, pero ya no deberíamos manejar contraseñas con C al menos que sea para tareas o cosas divertidas.

Explicando el algoritmo

Necesitamos una forma de leer cada carácter o tecla presionada sin que el usuario presione Enter. En Windows existe getch, que nos da la tecla presionada, misma que fácilmente puede ser convertida a char.

Por cada carácter leído lo convertimos a cadena y lo concatenamos a la contraseña leída.

Estoy manejando 2 casos especiales: cuando se presiona la tecla de borrado y cuando se presiona Enter; en ese caso los códigos de las mismas son 8 y 13 respectivamente.

Leer contraseña en C sin mostrar caracteres escritos (mostrar asteriscos)

Cuando se presiona la tecla de borrado, eliminamos el último carácter de nuestra cadena. Y cuando se presiona Enter suponemos que el usuario terminó de escribir su contraseña.

Finalmente, cada que el usuario presiona una tecla limpiamos la pantalla y enmascaramos la cadena. Esto solo es necesario si enmascaras la cadena.

Nota: seguramente debe haber algunas teclas que no estoy tomando en cuenta, por ejemplo si el usuario quiere mover la posición del cursor con una tecla de dirección, o cosas de esas.

Leer contraseña en C

Vamos a la función. He encerrado todo el comportamiento en un método para poder invocarlo cuantas veces sea necesario.

Por cierto, esta función no regresa la cadena, simplemente coloca la contraseña en la cadena de destino que tú le indiques, por lo que debes declarar la string antes y enviar el apuntador a la misma.

void leerContrasenaSinMostrarla(char *palabraSecretaDestino)
{
    int caracterLeido = 0;
    char temporal[2];
    while (caracterLeido != TECLA_ENTER)
    {
        limpiarPantalla();
        printf("Ingresa tu palabra secreta: ");
        enmascaraCadena(palabraSecretaDestino, strlen(palabraSecretaDestino), MASCARA);
        caracterLeido = getch();
        // https://parzibyte.me/blog/2019/11/02/c-char-a-string/
        temporal[0] = caracterLeido;
        temporal[1] = '\0';
        if (caracterLeido == TECLA_BORRAR)
        {
            if (strlen(palabraSecretaDestino) > 0)
            {
                // https://parzibyte.me/blog/2022/03/23/eliminar-ultimo-caracter-cadena-c/
                palabraSecretaDestino[strlen(palabraSecretaDestino) - 1] = '\0';
            }
        }
        else if (caracterLeido != TECLA_ENTER)
        {
            strncat(palabraSecretaDestino, temporal, 1);
        }
    }
}

Hacemos un ciclo que se va a detener cuando el usuario presione Enter. Dentro del ciclo vemos si el usuario presionó el backspace para eliminar el último char, y en caso de que no, vemos si presionó algo distinto al Enter para concatenar ese carácter a la contraseña.

Fíjate en que tenemos dos funciones extras: la de enmascarar la cadena (que hace tiempo también hice con Arduino) y la que limpia la pantalla.

Enmascarar cadena

Para mostrar asteriscos en lugar de la cadena real, simplemente imprimimos un carácter desde 0 hasta la longitud de la cadena menos 1. Así:

void enmascaraCadena(char *cadena, int longitud, char mascara)
{
    int i = 0;
    for (i = 0; i < longitud; i++)
    {
        printf("%c", mascara);
    }
}

Limpiar pantalla

Existen varias formas de limpiar la pantalla, y también depende de la plataforma, terminal, sistema operativo y creo que también del estado de ánimo del programador.

Yo he usado la siguiente función:

void limpiarPantalla()
{

    // system("cls"); // Comentar en Linux y descomentar en Windows
    printf("\e[1;1H\e[2J"); // Comentar en Windows y descomentar en Linux
}

Por cierto este es un buen lugar para documentar que en ocasiones la limpieza de pantalla modificaba la cadena y no permitía eliminar el carácter. Todo muy raro, pero al final ya no me pasó.

Poniendo todo junto

Finalmente, para leer una cadena sin mostrarla, y en su lugar mostrar asteriscos ya sea en C o C++ tenemos el siguiente código junto con su implementación en el main:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <conio.h>

#define TECLA_BORRAR 8
#define TECLA_ENTER 13
#define MAXIMA_LONGITUD_CADENA 1000
#define MASCARA '*'

/*
    https://parzibyte.me/blog
*/
void limpiarPantalla()
{

    // system("cls"); // Comentar en Linux y descomentar en Windows
    printf("\e[1;1H\e[2J"); // Comentar en Windows y descomentar en Linux
}

void enmascaraCadena(char *cadena, int longitud, char mascara)
{
    int i = 0;
    for (i = 0; i < longitud; i++)
    {
        printf("%c", mascara);
    }
}

void leerContrasenaSinMostrarla(char *palabraSecretaDestino)
{
    int caracterLeido = 0;
    char temporal[2];
    while (caracterLeido != TECLA_ENTER)
    {
        limpiarPantalla();
        printf("Ingresa tu palabra secreta: ");
        enmascaraCadena(palabraSecretaDestino, strlen(palabraSecretaDestino), MASCARA);
        caracterLeido = getch();
        // https://parzibyte.me/blog/2019/11/02/c-char-a-string/
        temporal[0] = caracterLeido;
        temporal[1] = '\0';
        if (caracterLeido == TECLA_BORRAR)
        {
            if (strlen(palabraSecretaDestino) > 0)
            {
                // https://parzibyte.me/blog/2022/03/23/eliminar-ultimo-caracter-cadena-c/
                palabraSecretaDestino[strlen(palabraSecretaDestino) - 1] = '\0';
            }
        }
        else if (caracterLeido != TECLA_ENTER)
        {
            strncat(palabraSecretaDestino, temporal, 1);
        }
    }
}

int main()
{
    char palabraSecreta[MAXIMA_LONGITUD_CADENA] = "";
    leerContrasenaSinMostrarla(palabraSecreta);
    // Nota: obviamente si no quieres mostrarla no la muestres, de todos modos la contraseña ya estará en palabraSecreta
    printf("\nLo que escribiste es: '%s'", palabraSecreta);
    return 0;
}

En el main defino mi cadena (línea 61) y la envío a la función leerContrasenaSinMostrarla. Cuando el usuario presione Enter, la función terminará y yo tendré la contraseña leída desde C.

Recuerda que tú decides qué hacer con la contraseña. Yo la muestro por motivos de prueba, pero tú puedes hacer cualquier otra cosa.

Para terminar te dejo con más tutoriales de C en mi blog.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Entradas recientes

Servidor HTTP en Android con Flutter

El día de hoy te mostraré cómo crear un servidor HTTP (servidor web) en Android…

7 días hace

Imprimir automáticamente todos los PDF de una carpeta

En este post te voy a enseñar a designar una carpeta para imprimir todos los…

1 semana hace

Guía para imprimir en plugin versión 1 desde Android

En este artículo te voy a enseñar la guía para imprimir en una impresora térmica…

2 semanas hace

Añadir tasa de cambio en sistema de información

Hoy te voy a mostrar un ejemplo de programación para agregar un módulo de tasa…

3 semanas hace

Comprobar validez de licencia de plugin ESC POS

Los usuarios del plugin para impresoras térmicas pueden contratar licencias, y en ocasiones me han…

3 semanas hace

Imprimir euro € en impresora térmica

Hoy voy a enseñarte cómo imprimir el € en una impresora térmica. Vamos a ver…

4 semanas hace

Esta web usa cookies.