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
\text{A}\mapsto 0,\\ \text{B}\mapsto 1,\\ \dots,\\ \text{Z}\mapsto 25.
  • 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
y_i \equiv \sum_{j=1}^{n} a_{ij}\,x_j \pmod{26},\qquad i=1,\dots,n.
  • 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:
    1. limpar a mensagem (manter apenas letras e transformar em maiúsculas),
    2. converter letras em números com a regra \text{A}\mapsto 0,\dots,
    3. aplicar padding com \text{X} se necessário,
    4. quebrar em blocos de tamanho n,
    5. para cada bloco, calcular \mathbf{y}=A\mathbf{x}\pmod{26},
    6. converter os y_i para letras e concatenar o resultado,
    7. 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.
  • Multiplicar:
\mathbf{y} = A\mathbf{x} = \begin{pmatrix}3 & 3\\\\ 2 & 5\end{pmatrix} \begin{pmatrix}7\\\ 8\end{pmatrix} = \begin{pmatrix}3\cdot 7 + 3\cdot 8\\\\ 2\cdot 7 + 5\cdot 8\end{pmatrix} = \begin{pmatrix}21+24\\\ 14+40\end{pmatrix} = \begin{pmatrix}45\\\ 54\end{pmatrix}.
  • Reduzir módulo 26:
45 \bmod 26 = 19,\qquad 54 \bmod 26 = 2.
  • 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.

def ler_matriz_quadrada():
    while True:
        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.")
                continue
            print(f"Agora digite {n} linhas, cada uma com {n} inteiros separados por espaço (linhas da matriz A):")
            A = []
            for i in range(n):
                linha = input(f"Linha {i+1}: ").strip().split()
                if len(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")


def limpa_mensagem(msg):
    # Mantém apenas letras A-Z e transforma em maiúsculas
    return ''.join([c for c in msg.upper() if c.isalpha()])


def texto_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 in range(0, len(nums), n)]
    return blocos


def multiplica_matriz_vetor(A, x):
    n = len(A)
    y = []
    for i in range(n):
        s = 0
        for j in range(n):
            s += A[i][j] * x[j]
        y.append(s % 26)
    return y


def blocos_para_texto(blocos):
    chars = []
    for bloco in blocos:
        for num in bloco:
            chars.append(chr(num + ord('A')))
    return ''.join(chars)


def cadastrar_matriz():
    print("Cadastro da matriz codificadora A:")
    A = ler_matriz_quadrada()
    print("Matriz A cadastrada com sucesso.")
    return A


def criptografar_mensagem(A):
    if A is None:
        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)
    if len(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)


def menu():
    A = None
    while True:
        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.")
            break
        else:
            print("Opção inválida. Tente novamente.")


if __name__ == "__main__":
    menu()

Exercícios relacionados