A estocasticidade (ou aleatoriedade) é um dos pilares de qualquer sistema de segurança. Em geradores de números aleatórios, quão mais aleatória e incerta é a geração dos dados, melhor a qualidade daquele gerador e mais seguro é o seu uso em sistema de criptografia ponta-a-ponta, funções de hash, geração de chaves PGP, entre outros.
Sabendo disso, você decidiu usar essa geração de números aleatórios para criar um gerador de senhas seguras. Para ser considerada segura, a sua senha deve ter 8 caracteres. Esses 8 caracteres devem ser distribuídos entre:
- 2 números
- 2 letras maiúsculas
- 2 letras minúsculas
- 2 símbolos especiais (, ; #, $, %, &)
Crie uma função em C que gera uma senha segura de 8 caracteres seguindo as regras acima. Dica: gere números aleatórios e consulte a tabela ASCII para converter de números para caracteres.
Passo 1
O enunciado pede uma função em C que gere uma senha de exatamente
caracteres, contendo:
-
dígitos numéricos ( – ) -
letras maiúsculas ( – ) -
letras minúsculas ( – ) -
símbolos especiais escolhidos entre ,
,;
,#
,$
,%
,&
O conteúdo principal envolve: gerar números aleatórios com
rand()
, converter esses valores para caracteres usando a tabela ASCII e embaralhar os caracteres para não virem agrupados por tipo.Passo 2
Definir os conjuntos de caracteres permitidos e a função de sorteio. Vamos criar quatro strings constantes contendo cada categoria:
const char *digits \(=\) "\(0123456789\)";
const char *uppers \(=\) "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char *lowers \(=\) "abcdefghijklmnopqrstuvwxyz";
const char *symbols \(=\) ",;#$%&";
Cada string servirá de “lookup” para selecionarmos um caractere aleatório dentro dela usando
rand()
e o tamanho da string.Passo 3
Alocar um vetor de
posições para armazenar a senha (
caracteres mais o terminador nulo) e, em seguida, sortear
caracteres de cada categoria:
char password[9];
for (int i = 0; i < 2; i++) {
password[i] = digits[rand() % 10];
password[i+2] = uppers[rand() % 26];
password[i+4] = lowers[rand() % 26];
password[i+6] = symbols[rand() % 6];
}
Isso preenche as posições
\(0,1\)
com dígitos,\(2,3\)
com maiúsculas,\(4,5\)
com minúsculas,\(6,7\)
com símbolos.
Passo 4
Embaralhar os
caracteres para que os tipos fiquem distribuídos de forma aleatória. Podemos usar o algoritmo Fisher–Yates:
for (int i = 7; i > 0; i--) {
int j = rand() % (i + 1);
char tmp = password[i];
password[i] = password[j];
password[j] = tmp;
}
Em seguida, garantimos o terminador de string:
password[8] = '\0';
Passo 5
Preparar a função completa, incluindo a semente para
rand()
, por exemplo vinda de time(NULL)
, e um protótipo que retorne ou imprima a senha.Resposta
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void generate_password(char password[9]) {
const char *digits = "0123456789";
const char *uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char *lowers = "abcdefghijklmnopqrstuvwxyz";
const char *symbols = ",;#$%&";
// Gera \(2\) de cada categoria
for (int i = 0; i < 2; i++) {
password[i] = digits[rand() % 10];
password[i+2] = uppers[rand() % 26];
password[i+4] = lowers[rand() % 26];
password[i+6] = symbols[rand() % 6];
}
// Embaralha com Fisher--Yates
for (int i = 7; i > 0; i--) {
int j = rand() % (i + 1);
char tmp = password[i];
password[i] = password[j];
password[j] = tmp;
}
password[8] = '\0';
}
int main() {
srand((unsigned)time(NULL));
char pwd[9];
generate_password(pwd);
printf("Senha gerada: %s\n", pwd);
return 0;
}