OneCompiler

Atividade 2 P2

Links dos cógidos:

Teorema chinês do resto: https://onecompiler.com/c/436s2ssa7
Criptografia RSA: https://onecompiler.com/c/436s2vdt2
CPF e ISBN: https://onecompiler.com/c/436s2xejn

Códigos na integra:

Teorema chinês do resto

#include <stdio.h>

#define MAX_EQUATIONS 4
int num_equations;

int euclidesEstendido(int a, int b, int *x, int *y){
    if(b == 0){
        *x = 1;
        *y = 0;
        return a;
    }

    int x1, y1;
    int mdc = euclidesEstendido(b, a % b, &x1, &y1);
    *x = y1;
    *y = x1 - (a / b) * y1;
    return mdc;
}

int inverso(int a, int m){
    int x, y;
    int mdc = euclidesEstendido(a, m, &x, &y);

    if(mdc != 1){
        printf("O inverso modular não existe\n");
        return 0;
    } 

    if(x < 0){
        x = x + m;
    }

    return x;
}

int chines(int *r, int *m){
    int N = 1;  
    int n[num_equations]; 
    int inversos[num_equations];
    int multiplicado = 0;

    for(int i = 0; i < num_equations; i++){ // definir N
        N *= m[i];
    }


    for(int i = 0; i < num_equations; i++){ // definir n1, n2 e n3
        n[i] = N / m[i];
        inversos[i] = inverso(n[i], m[i]); // calcular o inverso
    }  

    for(int i = 0; i < num_equations; i++){ // multiplicar todos
        multiplicado += r[i] * n[i] * inversos[i];
    }  

    return multiplicado % N;
}

int main() {
    printf("Quantas equações você deseja inserir (até %d)? ", MAX_EQUATIONS);
    scanf("%d", &num_equations);

    if (num_equations > MAX_EQUATIONS || num_equations <= 0) {
        printf("Número de equações inválido. Deve ser entre 1 e %d.\n", MAX_EQUATIONS);
        return 1;
    }

    int r[num_equations];
    int m[num_equations];

    for (int i = 0; i < num_equations; i++) {
        printf("Digite o resto 'r' e o módulo 'm' para a equação %d (na forma 'r m'):\n", i + 1);
        scanf("%d %d", &r[i], &m[i]);
    }

    printf("As equações inseridas são:\n");
    for (int i = 0; i < num_equations; i++) {
        printf("x ≡ %d (mod %d)\n", r[i], m[i]);
    }

    int x = chines(r, m);
    printf("A solução é %d\n", x);

    return 0;
}

Criptografia RSA:

#include <stdio.h>
#include <string.h>
#include <math.h>

long long mod_exp(long long base, long long exp, long long mod) {
    long long result = 1;
    base = base % mod;  

    while (exp > 0) {
        if (exp % 2 == 1) {  
            result = (result * base) % mod;
        }
        base = (base * base) % mod;  
        exp = exp / 2;  
    }

    return result;
}

long long codifica(long long m, int e, int n) {
    return mod_exp(m, e, n);  
}

long long bloco_para_numero(char bloco[], int tamanho) {
    long long numero = 0;
    for (int i = 0; i < tamanho; i++) {
        numero = numero * 36 + (bloco[i] - 'A' + 10);  
    }
    return numero;
}

int main() {
    char mensagem[100]; 
    int p, q, e, tamanho;

    printf("Digite a palavra que você quer codificar, em letras maiúsculas\n");
    scanf("%s", mensagem);

    printf("Digite os dois números primos 'p' e 'q' (na forma 'p q')\n");
    scanf("%d %d", &p, &q);

    printf("Agora, digite o número 'e' e o tamanho do bloco 't' (na forma 'e t')\n");
    scanf("%d %d", &e, &tamanho); 

    int n = p * q; 

    int mensagem_len = strlen(mensagem);

    printf("A mensagem codificada é: ");
    for (int i = 0; i < mensagem_len; i += tamanho) {
        char bloco[tamanho + 1];
        int j;
        
        for (j = 0; j < tamanho && (i + j) < mensagem_len; j++) {
            bloco[j] = mensagem[i + j];
        }
        bloco[j] = '\0';  

        long long numero_bloco = bloco_para_numero(bloco, j);

        long long codificado = codifica(numero_bloco, e, n);

        printf("%lld", codificado);
        
        if (i + tamanho < mensagem_len) {
            printf(" - ");
        }
    }
    printf("\n");

    return 0;
}

CPF e ISBN:

#include <stdio.h>
#include <string.h>
#include <math.h>

int calcula_verificador_cpf(int soma){
    return soma % 11;
}

int calcula_verificador_isbn(int soma){
    soma *= -1;
    int D = soma % 11;

    while (D < 0) {
        D += 11;
    }

    return D;
}

int main() {
    long numero;
    int primeiros[9];
    int soma = 0;
    int option;

    printf("Digite 1 para calcular cpf e 2 para caluclar ISBN\n");
    scanf("%d", &option);

    if(option == 1){
        printf("Digite os 9 primeiros dígitos do CPF no formato XXXXXXXXX\n");
        scanf("%ld", &numero);

        for (int i = 8; i >= 0; i--) {
            primeiros[i] = numero % 10;
            numero = numero / 10;
        }

        for (int i = 0; i < 9; i++) {
            soma += primeiros[i] * (i + 1);
        }

        int verificador1;
        int verificador2;

        verificador1 = calcula_verificador_cpf(soma);

        soma = 0;
        for (int i = 0; i < 9; i++) {
            soma += primeiros[i] * i;
        }

        soma += 9 * verificador1;
        verificador2 = calcula_verificador_cpf(soma);

        printf("O dígito verificador é %d%d\n", verificador1, verificador2);
    } else {
        printf("Digite os 9 primeiros dígitos do ISBN no formato XXXXXXXXX\n");
        scanf("%ld", &numero);

        for (int i = 8; i >= 0; i--) {
            primeiros[i] = numero % 10;
            numero = numero / 10;
        }

        for (int i = 0; i < 9; i++) {
            soma += primeiros[i] * (10 - i);
        }

        int verificador;
        verificador = calcula_verificador_isbn(soma);

        printf("O dígito verificador é %d\n", verificador);
    }

    

    return 0;
}