Opção para permitir que o usuário digite a mensagem a ser criptografada. O programa deverá executar o processo de criptografia, multiplicando as matrizes e em seguida mostrar na tela a mensagem codificada. Caso a matriz codificadora ( A ) ainda não tenha sido armazenada, o programa deverá imprimir uma mensagem de erro, informando ao usuário que a matriz (A) deve ser cadastrada.
Passo 1
O enunciado pede que eu adicione uma opção ao programa que permita ao usuário digitar uma mensagem para ser criptografada. As exigências e informações fornecidas são:
O programa deve aceitar uma mensagem digitada pelo usuário e executar o processo de criptografia multiplicando matrizes.
Após a multiplicação, o programa deve mostrar na tela a mensagem codificada.
Se a matriz codificadora A ainda não tiver sido armazenada (ou cadastrada), o programa deve imprimir uma mensagem de erro informando que a matriz A deve ser cadastrada.
Não foram dadas restrições explícitas sobre alfabeto, operação aritmética ou formato da matriz; portanto, preciso escolher convenções razoáveis e explicá-las (e implementar um programa que as siga).
Passo 2
Vou explicitar as convenções escolhidas para que a criptografia fique bem definida (essas escolhas são as mais comuns em exercícios deste tipo):
Alfabeto: serão usadas apenas letras maiúsculas de A até Z. Ou seja, antes de criptografar, a mensagem será “limpa”: serão removidos caracteres não-alfabéticos (espaços, pontuação e dígitos) ou opcionalmente podem ser ignorados; aqui escolho remover tudo que não for letra e transformar em maiúsculas.
Mapeamento letra → número: cada letra será convertida para um número conforme
Operação numérica: as operações são feitas módulo 26 (tamanho do alfabeto). Isso garante que o resultado volte a um número entre 0 e 25.
Blocos e dimensão da matriz: a matriz codificadora A será uma matriz quadrada de dimensão n\times n. A mensagem é dividida em blocos de n letras; cada bloco vira um vetor coluna \mathbf{x}\in\mathbb{Z}_{26}^n. Para cada bloco calculamos o vetor cifrado
\mathbf{y} = A\,\mathbf{x} \pmod{26}.
Preenchimento (padding): se o último bloco tiver menos de n letras, ele será completado com a letra \text{X} (que corresponde a 23) até preencher n posições.
Essas escolhas definem precisamente como multiplicar a matriz pelo vetor mensagem e como obter a saída alfabética.
Passo 3
A ideia matemática da criptografia por blocos (tipo Hill cipher) é esta:
Seja A uma matriz n\times n com entradas inteiras (representando coeficientes da codificação).
Dada uma mensagem transformada num bloco \mathbf{x}=(x_1,x_2,\dots,x_n)^\top com x_j\in\{0,\dots,25\}, o bloco cifrado é o vetor \mathbf{y} com coordenadas
Para cada bloco fazemos essa multiplicação; concatenando todos os vetores cifrados obtemos a mensagem codificada (convertendo os y_i novamente para letras via 0\mapstoA, \dots, 25\mapstoZ).
Explicando cada símbolo:
a_{ij} é o elemento da linha i e coluna j da matriz A.
x_j é a j-ésima entrada do vetor de mensagem do bloco (número entre 0 e 25).
y_i é a i-ésima entrada do vetor cifrado resultante.
A notação \pmod{26} significa que, após somar e multiplicar, tomamos o resto da divisão por 26 para garantir que y_i esteja em 0,\ldots,25.
Passo 4
Algumas decisões de implementação e validações necessárias no programa:
Verificar se a matriz A foi cadastrada: manter uma variável (por exemplo, A = None inicialmente). Quando o usuário escolhe a opção de cadastrar A, essa variável passa a referenciar a matriz (lista de listas).
Ao tentar cifrar uma mensagem, o código deve checar if A is None: e, nesse caso, imprimir a mensagem de erro solicitada explicando que a matriz A deve ser cadastrada.
Ao cadastrar A, o programa deve checar que a matriz é quadrada (número de linhas igual ao de colunas) e que as entradas são inteiros. Se não for, informar erro e pedir de novo.
A função de criptografia deve:
limpar a mensagem (manter apenas letras e transformar em maiúsculas),
converter letras em números com a regra \text{A}\mapsto 0,\dots,
aplicar padding com \text{X} se necessário,
quebrar em blocos de tamanho n,
para cada bloco, calcular \mathbf{y}=A\mathbf{x}\pmod{26},
converter os y_i para letras e concatenar o resultado,
mostrar na tela a mensagem codificada (como texto). Opcionalmente também mostrar a sequência de números.
Passo 5
Vou mostrar passo a passo pequeno exemplo manual (para entender antes do código). Suponha que a matriz cadastrada seja
A = \begin{pmatrix}3 & 3\\\\ 2 & 5\end{pmatrix},
ou seja, n=2. Mensagem de exemplo: “HI”.
Converter letras: H\mapsto 7,\\ I\mapsto 8. Então \mathbf{x}=(7,8)^\top.
Converter de volta: 19\mapsto \text{T},\\\ 2\mapsto \text{C}. Resultado cifrado: “TC”.
Esse mini-exemplo mostra como funciona a multiplicação e o módulo.
Passo 6
Agora, explico como transformar isso em código de forma clara e passo a passo (estratégia que vou implementar no programa em Python):
Função para cadastrar A: lê dimensão n (inteiro), depois lê n linhas onde cada linha contém n inteiros separados por espaço; valida ser quadrada e inteiros; armazena em A.
Função limpa_mensagem(msg): remove tudo que não for letra e retorna msg.upper() contendo só A–Z.
Função texto_para_blocos(msg, n): converte cada letra em número com ord\text{(c)}-ord('A'), aplica padding com X (número 23) se necessário, retorna lista de blocos (cada bloco é lista de n números).
Função multiplica_matriz_vetor(A, x): efetua produto A\mathbf{x} com aritmética inteira e devolve vetor com cada componente reduzida módulo 26.
Função blocos_para_texto(blocos_cifrados): converte cada número 0..25 de volta para letra via chr(y+ord('A')) e concatena.
Opção de menu “Criptografar mensagem”: verifica se A foi cadastrada; se não, imprime erro; se sim, pede mensagem, processa e exibe resultado.
No código, todos os passos (entrada, verificações, transformações) estarão comentados para facilitar entendimento na hora da prova.
Passo 7
Observações práticas que ajudam durante a prova/implementação:
A operação módulo 26 serve para que qualquer resultado numérico volte a um código de letra válido. Sem essa redução, os números poderiam sair de faixa.
Usar X como caractere de preenchimento é convencional; poderia ser outra letra, mas escolha e documente.
A matriz A não precisa ser invertível para cifrar, mas para decifrar (se isso for pedido) seria necessário que A tivesse inversa módulo 26. Aqui só é exigida a cifragem.
Para testes rápidos no exercício, usar matrizes pequenas (2×2 ou 3×3) facilita a checagem manual.
No programa, é importante validar entradas do usuário (por exemplo, impedir que o usuário cadastre uma matriz não quadrada).
Passo 8
Vou agora fornecer a implementação prática (um programa em Python). O programa inclui:
menu simples com opções para cadastrar A e criptografar mensagem;
checagem se A está cadastrado antes de criptografar;
implementação sem bibliotecas externas (apenas listas e operações básicas);
comentários e mensagens em português para facilitar o uso.
Resposta
#!/usr/bin/env python3# Programa simples para cadastrar uma matriz codificadora A e criptografar mensagens# usando multiplicação de matrizes módulo 26 (Hill-like cipher).# Implementação sem dependências externas.defler_matriz_quadrada():
whileTrue:
try:
n_str = input("Digite a dimensão n (inteiro > 0) da matriz A (n x n): ").strip()
n = int(n_str)
if n <= 0:
print("Dimensão deve ser um inteiro positivo. Tente novamente.")
continueprint(f"Agora digite {n} linhas, cada uma com {n} inteiros separados por espaço (linhas da matriz A):")
A = []
for i inrange(n):
linha = input(f"Linha {i+1}: ").strip().split()
iflen(linha) != n:
raise ValueError(f"Esperado {n} valores na linha {i+1}.")
row = [int(x) for x in linha]
A.append(row)
return A
except ValueError as e:
print("Entrada inválida:", e)
print("Vamos tentar novamente.\n")
deflimpa_mensagem(msg):
# Mantém apenas letras A-Z e transforma em maiúsculasreturn''.join([c for c in msg.upper() if c.isalpha()])
deftexto_para_blocos(msg_limpo, n):
nums = [ord\text{(c)} - ord('A') for c in msg_limpo]
# padding com 'X' -> 23
pad = (-len(nums)) % n
nums += [23] * pad
blocos = [nums[i:i+n] for i inrange(0, len(nums), n)]
return blocos
defmultiplica_matriz_vetor(A, x):
n = len(A)
y = []
for i inrange(n):
s = 0for j inrange(n):
s += A[i][j] * x[j]
y.append(s % 26)
return y
defblocos_para_texto(blocos):
chars = []
for bloco in blocos:
for num in bloco:
chars.append(chr(num + ord('A')))
return''.join(chars)
defcadastrar_matriz():
print("Cadastro da matriz codificadora A:")
A = ler_matriz_quadrada()
print("Matriz A cadastrada com sucesso.")
return A
defcriptografar_mensagem(A):
if A isNone:
print("Erro: a matriz (A) deve ser cadastrada antes de criptografar.")
return
n = len(A)
msg = input("Digite a mensagem a ser criptografada: ")
msg_limpa = limpa_mensagem(msg)
iflen(msg_limpa) == 0:
print("Mensagem não contém letras. Nada a criptografar.")
return
blocos = texto_para_blocos(msg_limpa, n)
blocos_cifrados = []
for bloco in blocos:
y = multiplica_matriz_vetor(A, bloco)
blocos_cifrados.append(y)
texto_cifrado = blocos_para_texto(blocos_cifrados)
print("Mensagem original (limpa, só letras maiúsculas):", msg_limpa)
print("Mensagem cifrada:", texto_cifrado)
defmenu():
A = NonewhileTrue:
print("\n--- Menu ---")
print("1. Cadastrar matriz codificadora A")
print("2. Criptografar mensagem")
print("3. Sair")
opc = input("Escolha uma opção (1/2/3): ").strip()
if opc == '1':
A = cadastrar_matriz()
elif opc == '2':
criptografar_mensagem(A)
elif opc == '3':
print("Saindo.")
breakelse:
print("Opção inválida. Tente novamente.")
if __name__ == "__main__":
menu()