Atividade 2 - P2 - 200043030
Atividade 2 - Matemática Discreta II P2 - 200043030
Q9 - Teorema Chines
https://onecompiler.com/c/436s2v5x9
Input:
4 --> Quant. de equações
2 3 --> Eq. linear 1 (onde 2 é "a" e 3 é "b", sendo equivalente a "x ≡ 2 mod 3")
5 7 --> Eq. linear 2 (seguindo a mesma regra acima)
13 5 --> Eq. linear 3
2 11 --> Eq. linear 4
Q10 - Cript RSA
https://onecompiler.com/c/436s3n8cd
Input:
5 3 3 1
ALMOCO BOM
O valores de "p", "q", "e", "tamanho do bloco" são inputados em série separados por espaço
A frase que deve ser codificado é inserida logo em seguida
Q11 - Calcula CPF e ISBN
https://onecompiler.com/c/436s4kk58
Input:
017869481
056394422
978123456789
Os primeiros 9 números formadores de um CPF
Os primeiros 9 números de um ISBN10
Os primeiros 12 números de um ISBN13
Todos os scripts estão no OneCompiler com a visibilidade como "Public", os scripts já estão com inputs de exemplo, mas caso seja necessário esse input poderá ser alterado desde que seja um input válido.
O script de cada solução pode ser encontrado logo a baixo:
Q9 - Teorema Chines
#include <stdlib.h>
typedef struct {
int a;
int n;
} Congruence;
int gcd(int a, int b) {
//algoritmo de Euclides
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
int extended_gcd(int a, int b, int *x, int *y) {
if (b == 0) {
*x = 1;
*y = 0;
return a;
}
int x1, y1;
int g = extended_gcd(b, a % b, &x1, &y1);
*x = y1;
*y = x1 - (a / b) * y1;
return g;
}
int chinese_remainder_theorem(Congruence *congruences, int size) {
int N = 1;
for (int i = 0; i < size; i++) {
N *= congruences[i].n;
}
int x = 0;
for (int i = 0; i < size; i++) {
int a_i = congruences[i].a;
int n_i = congruences[i].n;
int N_i = N / n_i;
int m_i, y;
int g = extended_gcd(N_i, n_i, &m_i, &y);
if (g != 1) {
// Os módulos não são coprimos
return -1;
}
int e_i = (m_i % n_i + n_i) % n_i;
x += a_i * e_i * N_i;
}
return (x % N + N) % N;
}
int main() {
printf("Digite o número de tuplas (máximo 4):\n");
int size;
scanf("%d", &size);
if (size < 1 || size > 4) {
printf("Número inválido de tuplas. Deve ser entre 1 e 4.\n");
return 1;
}
Congruence congruences[4];
printf("Digite as tuplas no formato a n (separadas por espaço):\n");
for (int i = 0; i < size; i++) {
if (scanf("%d %d", &congruences[i].a, &congruences[i].n) != 2) {
printf("Entrada inválida. Certifique-se de fornecer pares de inteiros no formato correto.\n");
return 1;
}
}
printf("O sistema de congruências inserido é:\n");
for (int i = 0; i < size; i++) {
printf("x ≡ %d mod %d\n", congruences[i].a, congruences[i].n);
}
int solution = chinese_remainder_theorem(congruences, size);
int N = 1;
for (int i = 0; i < size; i++) {
N *= congruences[i].n;
}
if (solution != -1) {
printf("A solução do sistema de congruências é x ≡ %d mod %d\n", solution, N);
} else {
printf("Os módulos fornecidos não são coprimos e o sistema não pode ser resolvido.\n");
}
return 0;
}
Q10 - Cript RSA
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int mdc(int a, int b) {
if (b == 0) {
return a;
}
return mdc(b, a % b);
}
int inverso_modular(int a, int m) {
a = a % m;
for (int x = 1; x < m; x++) {
if ((a * x) % m == 1) {
return x;
}
}
return -1;
}
int exp_modular(int base, int exp, int mod) {
int resultado = 1;
base = base % mod;
while (exp > 0) {
if (exp % 2 == 1) {
resultado = (resultado * base) % mod;
}
exp = exp >> 1;
base = (base * base) % mod;
}
return resultado;
}
void criptografar(char *mensagem, int e, int n, int tamanho_bloco) {
char alfabeto[27] = {0};
int index = 0;
for (int i = 0; i < 26; i++) {
alfabeto[i] = 11 + i;
}
int espaco = 0;
printf("Mensagem original: %s\n", mensagem);
printf("Mensagem criptografada:\n");
for (int i = 0; mensagem[i] != '\0'; i++) {
if (mensagem[i] == ' ') {
printf("%d ", espaco);
} else {
for (int j = 0; j < 26; j++) {
if (mensagem[i] == 'A' + j) {
index = alfabeto[j];
break;
}
}
int criptografado = exp_modular(index, e, n);
printf("%d ", criptografado);
}
}
printf("\n");
}
int main() {
int p, q, e, tamanho_bloco;
printf("Digite os valores para p, q, e e o tamanho do bloco:\n");
printf("p (primo): \n");
scanf("%d", &p);
printf("q (primo): \n");
scanf("%d", &q);
printf("e: \n");
scanf("%d", &e);
printf("Tamanho do bloco: \n");
scanf("%d", &tamanho_bloco);
int n = p * q;
int fi_n = (p - 1) * (q - 1);
if (mdc(e, fi_n) != 1) {
printf("Erro: 'e' deve ser coprimo de phi(n).\n");
return 1;
}
char mensagem[100];
printf("Digite a mensagem a ser criptografada (letras maiúsculas e espaços): ");
getchar();
fgets(mensagem, sizeof(mensagem), stdin);
criptografar(mensagem, e, n, tamanho_bloco);
return 0;
}
Q11 - Calcula CPF e ISBN
#include <stdio.h>
int calcular_dv_cpf(int cpf[], int n) {
int peso[] = {10, 9, 8, 7, 6, 5, 4, 3, 2};
int soma = 0;
for (int i = 0; i < n; i++) {
soma += cpf[i] * peso[i];
}
int resto = soma % 11;
return (resto < 2) ? 0 : 11 - resto;
}
int calcular_dv2_cpf(int cpf[], int n) {
int peso[] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2};
int soma = 0;
for (int i = 0; i < n; i++) {
soma += cpf[i] * peso[i];
}
int resto = soma % 11;
return (resto < 2) ? 0 : 11 - resto;
}
void calcular_cpf(long long cpf) {
int cpf_array[9];
for (int i = 8; i >= 0; i--) {
cpf_array[i] = cpf % 10;
cpf /= 10;
}
int dv1 = calcular_dv_cpf(cpf_array, 9);
cpf_array[9] = dv1;
int dv2 = calcular_dv2_cpf(cpf_array, 10);
printf("CPF: ");
for (int i = 0; i < 9; i++) {
printf("%d", cpf_array[i]);
}
printf(" - %d%d\n", dv1, dv2);
}
int calcular_dv_isbn10(int isbn[], int n) {
int soma = 0;
for (int i = 0; i < n; i++) {
soma += isbn[i] * (10 - i);
}
int resto = soma % 11;
return (resto == 0) ? 0 : 11 - resto;
}
int calcular_dv_isbn13(int isbn[], int n) {
int soma = 0;
for (int i = 0; i < n; i++) {
soma += isbn[i] * (i % 2 == 0 ? 1 : 3);
}
int resto = soma % 10;
return (resto == 0) ? 0 : 10 - resto;
}
void calcular_isbn10(long long isbn10) {
int isbn_array[9];
for (int i = 8; i >= 0; i--) {
isbn_array[i] = isbn10 % 10;
isbn10 /= 10;
}
int dv = calcular_dv_isbn10(isbn_array, 9);
printf("ISBN-10: ");
for (int i = 0; i < 9; i++) {
printf("%d", isbn_array[i]);
}
printf(" - %d\n", dv);
}
void calcular_isbn13(long long isbn13) {
int isbn_array[12];
for (int i = 11; i >= 0; i--) {
isbn_array[i] = isbn13 % 10;
isbn13 /= 10;
}
int dv = calcular_dv_isbn13(isbn_array, 12);
printf("ISBN-13: ");
for (int i = 0; i < 12; i++) {
printf("%d", isbn_array[i]);
}
printf(" - %d\n", dv);
}
int main() {
long long cpf, isbn10, isbn13;
printf("Digite os 9 primeiros dígitos do CPF (apenas números): \n");
scanf("%lld", &cpf);
calcular_cpf(cpf);
printf("Digite os 9 primeiros dígitos do ISBN-10 (apenas números): \n");
scanf("%lld", &isbn10);
calcular_isbn10(isbn10);
printf("Digite os 12 primeiros dígitos do ISBN-13 (apenas números): \n");
scanf("%lld", &isbn13);
calcular_isbn13(isbn13);
return 0;
}