Lista 2 - MD2
Lista 2
Aluno: Gabriel Lima da Silva
Matrícula: 222037610
Linguagem: C
Link no final!
9 - Teorema Chines do Resto
#include <stdio.h>
// Função para calcular o MDC
int mdc(int a, int b) {
if (b == 0) {
return a;
}
return mdc(b, a % b); // recursao mdc
}
// Função para calcular o inverso modular de "a" módulo "m"
int inverso_modular(int a, int m) {
int m0 = m, t, q;
int x0 = 0, x1 = 1;
if (m == 1)
return 0;
while (a > 1) {
// q é o quociente
q = a / m;
t = m;
// m é o resto agora
m = a % m;
a = t;
t = x0;
x0 = x1 - q * x0;
x1 = t;
}
// Ajusta x1 para ser positivo
if (x1 < 0)
x1 += m0;
return x1;
}
int main() {
int n;
printf("Ola professora! Digite o numero de equacoes (maximo 4):\n");
scanf("%d", &n);
if (n < 1 || n > 4) {
printf("Numero de equacoes invalido! Por favor, digite novamente.\n");
return 1;
}
// vetores para armazenar os restos e módulos das equações
int restos[4], modulos[4];
for (int i = 0; i < n; i++) {
printf("Digite o resto r%d e o modulo m%d, respectivamente:\n", i + 1, i + 1);
scanf("%d %d", &restos[i], &modulos[i]);
}
// Verifica se os módulos são coprimos dois a dois
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (mdc(modulos[i], modulos[j]) != 1) {
printf("Os modulos não são coprimos dois a dois!\n");
return 1;
}
}
}
// Calcula o produto total dos módulos -> x mod M
int M = 1;
for (int i = 0; i < n; i++) {
M *= modulos[i];
}
// Calcula a solução usando o Teorema Chinês do Resto
int x = 0; // X = C*N*Y+...
for (int i = 0; i < n; i++) {
int Mi = M / modulos[i];
int inv = inverso_modular(Mi, modulos[i]);
x += restos[i] * Mi * inv;
}
// Ajusta x para o intervalo [0, M)
x = (x % M + M) % M;
printf("Sua solucao:\nx = %d (mod %d)\n", x, M);
return 0;
}
10 - RSA
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
// Função para verificar se um número é primo
int ehPrimo(int num) {
if (num < 2) return 0;
for (int i = 2; i <= sqrt(num); i++) {
if (num % i == 0) return 0;
}
return 1;
}
// Função para calcular o MDC
int mdc(int a, int b) {
if (b == 0) {
return a;
}
return mdc(b, a % b); // recursao mdc
}
// Função para calcular o inverso modular de "a" módulo "m"
int inverso_modular(int a, int m) {
int m0 = m, t, q;
int x0 = 0, x1 = 1;
if (m == 1)
return 0;
while (a > 1) {
// q é o quociente
q = a / m;
t = m;
// m é o resto agora
m = a % m;
a = t;
t = x0;
x0 = x1 - q * x0;
x1 = t;
}
// Ajusta x1 para ser positivo
if (x1 < 0)
x1 += m0;
return x1;
}
// Função para realizar a exponenciação modular
long long exponenciacaoModular(long long base, long long exp, long long mod) {
long long resultado = 1;
base = base % mod;
while (exp > 0) {
if (exp % 2 == 1) {
resultado = (resultado * base) % mod;
}
exp = exp >> 1; // Divisão inteira por 2
base = (base * base) % mod;
}
return resultado;
}
void codificar_palavra(const char *texto, int *codigo, int tamanho) {
for (int i = 0; i < tamanho; i++) {
if (texto[i] >= 'A' && texto[i] <= 'Z') {
codigo[i] = 11 + (texto[i] - 'A'); // A - Z
} else if (texto[i] == ' ') {
codigo[i] = 37; // espaço
} else {
codigo[i] = 0; // invalido
}
}
}
void criptografar_palavra(int *texto, int tam, int e, int n, int *criptografada) {
for (int i = 0; i < tam; i++) {
long long resultado = 1;
int base = texto[i];
int exp = e;
while (exp > 0) {
if (exp % 2 == 1) {
resultado = (resultado * base) % n;
}
base = (base * base) % n;
exp /= 2;
}
criptografada[i] = (int)resultado;
}
}
int main() {
int p, q, e;
char palavra[100];
// Entrada dos números primos p e q
do {
printf("Digite os numeros primos p e q, respectivamente:\n");
scanf("%d %d", &p, &q);
if (!ehPrimo(p) || !ehPrimo(q)) {
printf("Ambos os numeros devem ser primos. Tente novamente.\n");
}
} while (!ehPrimo(p) || !ehPrimo(q));
// Calculando n e φ(n)
int n = p * q;
int phi = (p - 1) * (q - 1);
// Entrada do número E
do {
printf("Digite o numero E (deve ser coprimo com (n) = %d): ", phi);
scanf("%d", &e);
if (mdc(e, phi) != 1) {
printf("E deve ser coprimo com (n). Tente novamente.\n");
}
} while (mdc(e, phi) != 1);
// Calculando D (inverso modular de E)
int d = inverso_modular(e, phi);
if (d == -1) {
printf("Nao foi possível calcular o inverso modular de E.\n");
return 1;
}
// Entrada da palavra a ser criptografada
printf("Digite a palavra a ser criptografada (apenas letras maiusculas): ");
scanf("%s", palavra);
// tamanho da palavra
int tamanhoPalavra = strlen(palavra);
int palavraCodigo[256];
codificar_palavra(palavra, palavraCodigo, tamanhoPalavra);
// Criptografia
int criptografado[256];
criptografar_palavra(palavraCodigo, tamanhoPalavra, e, n, criptografado);
printf("Criptografando...\n");
for(int i = 0; i < tamanhoPalavra; i++) {
printf("%d ", criptografado[i]);
}
printf("\n");
// Exibindo chaves
printf("Chave publica: (E = %d, N = %d)\n", e, n);
printf("Chave privada: (D = %d, N = %d)\n", d, n);
return 0;
}
11 - CPF e ISBN
#include <stdio.h>
#include <string.h>
#include <ctype.h>
// Função para calcular o dígito verificador do CPF
int calcularDigitoCPF(const int cpf[], int pesoInicial) {
int soma = 0;
for (int i = 0; i < pesoInicial - 1; i++) {
soma += cpf[i] * (pesoInicial - i);
}
int resto = soma % 11;
return (resto < 2) ? 0 : 11 - resto;
}
// Função para validar um CPF e exibir os dígitos verificadores calculados
int validarCPF(const char* cpfStr) {
int cpf[11];
if (strlen(cpfStr) != 11) return 0;
for (int i = 0; i < 11; i++) {
if (!isdigit(cpfStr[i])) return 0;
cpf[i] = cpfStr[i] - '0';
}
int digito1 = calcularDigitoCPF(cpf, 10);
int digito2 = calcularDigitoCPF(cpf, 11);
printf("Digito verificador 1 calculado: %d\n", digito1);
printf("Digito verificador 2 calculado: %d\n", digito2);
return digito1 == cpf[9] && digito2 == cpf[10];
}
// Função para calcular o dígito verificador do ISBN-10
char calcularDigitoISBN(const int isbn[]) {
int soma = 0;
for (int i = 0; i < 9; i++) {
soma += isbn[i] * (i + 1);
}
int resto = soma % 11;
return (resto == 10) ? 'X' : resto + '0';
}
// Função para validar um ISBN-10 e exibir o dígito verificador calculado
int validarISBN(const char* isbnStr) {
int isbn[10];
if (strlen(isbnStr) != 10) return 0;
for (int i = 0; i < 9; i++) {
if (!isdigit(isbnStr[i])) return 0;
isbn[i] = isbnStr[i] - '0';
}
char digitoVerificadorCalculado = calcularDigitoISBN(isbn);
printf("Digito verificador calculado: %c\n", digitoVerificadorCalculado);
return digitoVerificadorCalculado == isbnStr[9];
}
int main() {
// Exemplo de CPF
char cpf[12];
printf("Ola professora! Bem vinda ao verificador de CPF e ISBN.\n");
printf("Digite um CPF (somente numeros): ");
scanf("%11s", cpf);
if (validarCPF(cpf)) {
printf("CPF valido!\n");
} else {
printf("CPF invalido!\n");
}
// Exemplo de ISBN-10
char isbn[11];
printf("Digite um ISBN-10 (9 numeros + digito verificador): ");
scanf("%10s", isbn);
if (validarISBN(isbn)) {
printf("ISBN valido!\n");
} else {
printf("ISBN invalido!\n");
}
return 0;
}
9- https://onecompiler.com/c/4369phrxn
10- https://onecompiler.com/c/4369qys4h
11- https://onecompiler.com/c/4369r4kvs