O Python já vem com tudo que você precisa para gerar senhas e tokens seguros. Sem pip install, sem dependências de terceiros — apenas a biblioteca padrão. Neste artigo, percorremos 10 padrões práticos de geração de senhas, da string aleatória mais simples até geração em lote pronta para produção. Todo snippet roda em Python 3.6+ puro.
Uma regra importante antes de começar: para qualquer coisa relacionada a segurança, use secrets em vez de random. O módulo random é projetado para modelagem e simulação, não para gerar tokens ou credenciais. Eles parecem quase idênticos no código, que é exatamente por que o erro é tão comum.
1. Senha Aleatória Básica
O ponto de partida mais simples. Escolha caracteres aleatórios de um conjunto misto de minúsculas, maiúsculas, dígitos e alguns símbolos.
import secrets
def generate_password(length=16):
chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%"
return "".join(secrets.choice(chars) for _ in range(length))
if __name__ == "__main__":
for i in range(5):
print(f"Password {i+1}: {generate_password()}")
Isso é perfeitamente adequado para muitos casos, mas não há garantia de que cada tipo de caractere apareça. Uma string de 16 caracteres poderia acabar toda em minúsculas por puro acaso. Se um serviço exige pelo menos um dígito ou símbolo, vá para o padrão 5.
2. Excluindo Caracteres Confusos
Caracteres como 0 vs O, ou 1 vs l são uma fonte recorrente de dor quando senhas são lidas em voz alta, impressas em papel ou olhadas em fonte minúscula no terminal.
import secrets
import string
def generate_password(length=16, excluded="0OIl1"):
all_chars = string.ascii_letters + string.digits + "!@#$%"
chars = "".join(c for c in all_chars if c not in excluded)
if not chars:
raise ValueError("No usable characters left.")
return "".join(secrets.choice(chars) for _ in range(length))
if __name__ == "__main__":
for i in range(5):
print(f"Password {i+1}: {generate_password()}")
Remover caracteres reduz o pool, o que diminui levemente a entropia por caractere. Na prática, adicionar um ou dois caracteres extras ao comprimento compensa de sobra. O ganho real é menos tickets de suporte que começam com “isso é zero ou O?“
3. Strings Aleatórias com Prefixo
Às vezes você precisa de um prefixo reconhecível — USER_, APIKEY_, um código de projeto — seguido de uma cauda aleatória. Isso é menos uma senha e mais um identificador com aleatoriedade embutida.
import secrets
import string
def generate_with_prefix(prefix="USER_", random_length=12):
chars = string.ascii_letters + string.digits
tail = "".join(secrets.choice(chars) for _ in range(random_length))
return prefix + tail
if __name__ == "__main__":
for i in range(5):
print(f"Key {i+1}: {generate_with_prefix()}")
Lembre-se: o prefixo adiciona zero entropia. Um prefixo de 6 caracteres mais 12 aleatórios é exatamente tão forte quanto 12 caracteres aleatórios. Prefixos são para humanos lendo logs, não para confundir atacantes.
4. Geração em Lote com Prefixo
A mesma ideia, mas gera um lote de uma vez. Útil ao integrar um grupo de usuários ou provisionar chaves de API.
import secrets
import string
def generate_batch(prefix="APIKEY_", random_length=16, count=5):
chars = string.ascii_letters + string.digits
return [
prefix + "".join(secrets.choice(chars) for _ in range(random_length))
for _ in range(count)
]
if __name__ == "__main__":
for i, key in enumerate(generate_batch(), 1):
print(f"Key {i}: {key}")
5. Mistura de Caracteres Garantida
Muitos serviços impõem regras: pelo menos uma maiúscula, um dígito, um símbolo. Este padrão satisfaz essas restrições reservando um slot por tipo exigido, depois preenchendo o resto aleatoriamente e embaralhando.
6. Senhas Legíveis por Humanos
Remova os caracteres mais confusos e elimine os símbolos. O resultado é um pouco mais fraco por caractere mas dramaticamente mais fácil de ditar por telefone, imprimir em carta de boas-vindas ou digitar no teclado do celular.
import secrets
import string
def generate_readable(length=16):
excluded = "0OIl1"
chars = "".join(
c for c in string.ascii_letters + string.digits
if c not in excluded
)
return "".join(secrets.choice(chars) for _ in range(length))
if __name__ == "__main__":
for i in range(5):
print(f"Password {i+1}: {generate_readable()}")
7. Frases de Senha Baseadas em Palavras
Junte palavras aleatórias com um separador. A frase de senha resultante é longa (bom para entropia) e memorável (bom para humanos). Essa é a abordagem famosamente ilustrada pelo XKCD #936.
import secrets
WORDS = [
"river", "cloud", "apple", "stone", "forest",
"ocean", "light", "shadow", "iron", "spark",
"maple", "crane", "drift", "ember", "frost",
"bloom", "cedar", "ridge", "pearl", "storm",
]
def generate_passphrase(word_count=4):
return "-".join(secrets.choice(WORDS) for _ in range(word_count))
if __name__ == "__main__":
for i in range(5):
print(f"Passphrase {i+1}: {generate_passphrase()}")
A lista de palavras de exemplo aqui é deliberadamente pequena. Em produção, use uma lista muito maior — a lista EFF Diceware tem 7.776 palavras. Com 4 palavras dessa lista, você obtém cerca de 51 bits de entropia.
8. Tokens Seguros para URL
Precisa de um token que possa ser embutido em uma URL sem se preocupar com encoding? secrets.token_bytes mais codificação Base64 URL-safe dá uma string limpa alfanumérica com traço e underscore.
import secrets
import base64
def generate_token(byte_length=24):
raw = secrets.token_bytes(byte_length)
return base64.urlsafe_b64encode(raw).decode().rstrip("=")
if __name__ == "__main__":
for i in range(5):
print(f"Token {i+1}: {generate_token()}")
9. Geração em Lote Personalizada
Especifique o comprimento e a quantidade, obtenha uma lista. Direto ao ponto.
import secrets
import string
def generate_batch(length=16, count=5):
chars = string.ascii_letters + string.digits + "!@#$%"
return [
"".join(secrets.choice(chars) for _ in range(length))
for _ in range(count)
]
if __name__ == "__main__":
for i, pw in enumerate(generate_batch(length=20, count=5), 1):
print(f"Password {i}: {pw}")
10. Geração em Lote Única
Quando você precisa garantir que não haja duplicatas — por exemplo, emitir códigos únicos para uma lista de usuários — colete resultados em um set até ter o suficiente.
import secrets
import string
def generate_unique(length=16, count=10):
chars = string.ascii_letters + string.digits + "!@#$%"
result = set()
while len(result) < count:
result.add("".join(secrets.choice(chars) for _ in range(length)))
return list(result)
if __name__ == "__main__":
for i, pw in enumerate(generate_unique(length=16, count=5), 1):
print(f"Senha {i}: {pw}")
Conclusão
Os 10 padrões usam apenas a biblioteca padrão do Python: secrets, string, random e base64. Sem instalações, sem dependências.
Para senhas de login, o padrão 5 costuma ser o ponto ideal. Para tokens de API, o padrão 8 é limpo e prático. Para senhas mestras digitadas por humanos, o padrão 7 vence em usabilidade.
E lembre-se: gerar uma senha forte é a parte fácil. Armazená-la com segurança, transmiti-la corretamente e rotacioná-la no prazo é onde o trabalho real começa.

Leave a Reply