$7R0NG
P455WorD?
Medidor de força de senhasAtaques força-bruta são aqueles que fazem várias tentativas para
tentar descobrir a senha de um usuário. Senhas muito curtas, senhas
com pouca variação de caracteres, palavras simples ou combinações de
teclado como qwert
são muito suscetíveis a estes
ataques.
Para tentar aumentar a segurança de seus usuários, muitos sistemas incluem um medidor de força de senhas que orientam o usuário sobre a resistência a ataques das senhas escolhidas. Nesta tarefa, implementaremos um programa com este objetivo que será baseado em um esquema de pontos, com bônus e penalidades.
Os seguintes fatores serão contabilizados para o cálculo da força de uma senha:
Tamanho: senhas de tamanho 8 serão consideradas adequadas. Senhas menores serão penalizadas e senhas mais longas serão bonificadas, de maneira linear, como descrito abaixo:
Tamanho (tam) | Bônus | Penalidade |
---|---|---|
tam > 8 | 2 * (tam - 8) | --- |
tam = 8 | --- | --- |
tam < 8 | --- | -4 * (8 - tam) |
Tipo dos caracteres: os caracteres serão classificados
em letras maiúsculas, minúsculas, dígitos decimais ou
especiais. Consideraremos caracteres especiais qualquer caractere
que o usuário possa digitar para fazer parte da senha que não seja
uma letra ou um dígito. Exemplos de caracteres especiais
são: ! @ # " $ % & * ( ) [ ] < > ?
. Uma senha
adequada deverá conter pelo menos dois caracteres de cada tipo,
como, por exemplo, IL0veY0u!!
. Penalizaremos a
ocorrência de um número insuficiente de caracteres de um tipo.
Número de caracteres de um determinado tipo | Penalidade |
---|---|
2 ou mais | --- |
1 | -4 |
0 | -8 |
Repetição de caracteres: senhas
como aaa555
ou ABABAB
são
indesejáveis. Consideraremos uma penalidade para repetições de um
mesmo caractere, não necessariamente em posições consecutivas na
senha.
Número de ocorrências de um mesmo caracter | Penalidade |
---|---|
até 2 | --- |
3 | -2 |
4 | -4 |
5 ou mais | -8 |
Consideraremos que letras minúsculas são diferentes de letras maiúculas e que as penalidades serão aplicadas a cada grupo encontrado. Por exemplo, a senha aaaAAA
receberia penalidade -4
por ter dois grupos de três caracteres repetidos.
Consideraremos que o valor inicial da pontuação é zero e este valor será acrescido dos bônus e penalidades descritos acima. A classificação final de uma senha será:
Pontuação (P) | Classificação |
---|---|
P ≥ 10 | Forte |
0 ≤ P < 10 | Suficiente |
-20 ≤ P < 0 | Fraca |
P < -20 | Insuficiente |
Importante: Esta classificação tem fins didáticos para treino de programação e não deve ser utilizada como guia para sistemas reais. Aspectos importantes como padrões de teclado, palavras comuns, grupos de caracteres e caracteres consecutivos não foram testados. Veja um pouco mais sobre o tema na Wikipedia, no verbete Password strength.
A entrada será composta por uma lista de senhas a serem classificadas. A primeira linha conterá o número de senhas e as linhas seguintes conterão uma senha cada uma.
5
iloveyou
ILoveYou
IL0veY0u
ILoveYou!!
IL0veY0u!!
Cada linha da saída conterá uma senha, sua classificação e sua pontuação entre parênteses, como no exemplo abaixo:
iloveyou: Insuficiente (-24)
ILoveYou: Fraca (-16)
IL0veY0u: Fraca (-8)
ILoveYou!!: Fraca (-4)
IL0veY0u!!: Suficiente (4)
Criamos um conjunto de testes com arquivos de
entrada arq<i>.in
e para cada um deles temos uma
saída esperada arq<i>.res
. Na
página testes-lab09.html
você pode conferir de maneira mais detalhada a pontuação de cada
senha para os testes abertos. No total, teremos seis testes abertos e dois testes fechados.
Algumas senhas contidas nos testes foram inspiradas em listas de senhas mais comuns.
Releia, se necessário, as instruções para fazer os testes em Testes com o SuSy.
Os seguintes métodos poderão ser úteis para a verificação dos tipos de caracteres:
Método | Verifica se a string contém apenas |
---|---|
isalpha() | letras |
isdigit() | dígitos decimais |
islower() | letras minúsculas |
isupper() | letras maiúsculas |
Para a contagem do número de ocorrências de caracteres nas senhas, poderão ser utilizados dicionários da seguinte forma:
>>> conta_caracteres = {}
>>> senha = "strongpassword"
>>> for c in senha:
if c not in conta_caracteres :
conta_caracteres[c] = 1
else:
conta_caracteres[c] += 1
>>> print(conta_caracteres)
{'s': 3, 't': 1, 'r': 2, 'o': 2, 'n': 1, 'g': 1, 'p': 1, 'a': 1, 'w': 1, 'd': 1}
Veja aqui a
página de submissão da tarefa. O arquivo a ser
submetido deve se chamar lab09.py. No
link Arquivos
auxiliares há um
arquivo aux09.zip
que
contém todos os arquivos de testes abertos, seus respectivos
resultados compactados e scripts para facilitar os testes.
O limite máximo será de 20 submissões. Serão considerados os resultados da última submissão.
O peso desta tarefa é 4.
O prazo final para submissão é 02/06/2019.
A nota desta tarefa é proporcional ao número de testes que executaram corretamente, desde que o código esteja coerente com o enunciado. A submissão de um código que não implementa o algoritmo requisitado, mas que exibe as saídas esperadas dos testes abertos a partir da comparação de trechos da entrada será considerada fraude e acarretará a atribuição de nota zero à média final da disciplina.