OneCompiler

Lista 2 de MD2

Questao 9

Desenvolver um código que calcule sistemas de congruência linear de até ### 4 equações utilizando o teorema chinês do resto (linguagens C ou C++)

#include <stdio.h>
#include <stdlib.h>

void limpaTerminal() {
#ifdef _WIN32
    system("cls");
#else
    system("clear");
#endif
}

int MDC(int num1, int num2){

    int aux;

    if(num1 % num2 == 0)
        return num2;
    else{
        aux = num2;
        num2 = num1 % num2;
        num1 = aux;
        return MDC(num1, num2);
    }

}

void imprimeMenu(){
    printf("***** Sistemas de congruencia pelo teorema chines do resto *****\n\n");
    printf("Resolve sistemas da forma ax = b mod n. \n\n");
}

int verificaQtdCongruencias(int qtdCongruencias){
    if(qtdCongruencias > 4 || qtdCongruencias < 1){
        printf("Qtd de congruencias invalido!\n");
        printf("Deve ser um valor entre 2 e 4. \n");
    }
    return 0;
}

int main(){

    int qtdCongruencias;

    imprimeMenu();

    printf("Digite quantas congruencias estao no sistema: ");
    scanf("%d", &qtdCongruencias);

    verificaQtdCongruencias(qtdCongruencias);

    int *a = (int*)malloc(qtdCongruencias * sizeof(int));
    int *b = (int*)malloc(qtdCongruencias * sizeof(int));
    int *n = (int*)malloc(qtdCongruencias * sizeof(int));
    int *M = (int*)malloc(qtdCongruencias * sizeof(int));
    int *X = (int*)malloc(qtdCongruencias * sizeof(int));

    for (int i = 0; i < qtdCongruencias; i++){
        limpaTerminal();
        printf("Nova Congruencia. \n\n");
        printf("Digite o valor a da congruencia: ");
        scanf("%d", &a[i]);
        printf("Digite o valor b da congruencia: ");
        scanf("%d", &b[i]);
        printf("Digite o valor n da congruencia: ");
        scanf("%d", &n[i]);
    }

    for (int i = 0; i < qtdCongruencias; i++){
        printf("%dx = %d mod %d \n", a[i], b[i], n[i]);
    }

    for (int i = 0; i < qtdCongruencias; i++){
        if(a[i] != 0){
            int inverso = 1;
            while((a[i]*inverso)%n[i] != 1){
                inverso++;
            }
            a[i] = 1;
            b[i] = (b[i]*inverso)%n[i];
        }
    }

    for(int i = 0; i < qtdCongruencias; i++){
        for(int j = i + 1; j < qtdCongruencias; j++){
            if(MDC(n[i], n[j]) != 1){
                printf("Nao e possivel resolver pelo teorema chines do resto. \n");
                    free(a);
                    free(b);
                    free(n);
                    free(M);
                    free(X);
                    return 0;
            }
        }
    }
        
    int N = 1;
    for(int i = 0; i < qtdCongruencias; i++){
        N *= n[i];
    }

    for(int i = 0; i < qtdCongruencias; i++){
        M[i] = N/n[i];
    }

    for (int i = 0; i < qtdCongruencias; i++){
        X[i] = 1;
        while((M[i]*X[i])%n[i] != 1){
            X[i]++;
        }
    }
        
        switch(qtdCongruencias){

            case 2: 
                printf("x = %d * %d * %d + %d * %d * %d mod %d \n", b[0], X[0], M[0], b[1], X[1], M[1], N);
                printf("x = %d + %d mod %d \n", b[0] * X[0] * M[0], b[1] * X[1] * M[1], N); 
                printf("x = %d mod %d \n", b[0] * X[0] * M[0] + b[1] * X[1] * M[1], N);
                printf("x = %d mod %d \n", (b[0] * X[0] * M[0] + b[1] * X[1] * M[1]) % N, N);
                break;

            case 3: 
                printf("x = %d * %d * %d + %d * %d * %d +  %d * %d * %d mod %d \n", b[0], X[0], M[0], b[1], X[1], M[1], b[2], X[2], M[2], N); 
                printf("x = %d + %d + %d mod %d \n", b[0] * X[0] * M[0], b[1] * X[1] * M[1], b[2] * X[2] * M[2], N);
                printf("x = %d mod %d \n", b[0] * X[0] * M[0] + b[1] * X[1] * M[1] + b[2] * X[2] * M[2], N);
                printf("x = %d mod %d \n", (b[0] * X[0] * M[0] + b[1] * X[1] * M[1] + b[2] * X[2] * M[2]) % N, N);
                break;

            case 4: 
                printf("x = %d * %d * %d + %d * %d * %d +  %d * %d * %d + %d * %d * %d mod %d \n", b[0], X[0], M[0], b[1], X[1], M[1], b[2], X[2], M[2], b[3], X[3], M[3], N); 
                printf("x = %d + %d + %d + %d mod %d \n", b[0] * X[0] * M[0], b[1] * X[1] * M[1], b[2] * X[2] * M[2], b[3] * X[3] * M[3], N);
                printf("x = %d mod %d \n", b[0] * X[0] * M[0] + b[1] * X[1] * M[1] + b[2] * X[2] * M[2] + b[3] * X[3] * M[3], N);
                printf("x = %d mod %d \n", (b[0] * X[0] * M[0] + b[1] * X[1] * M[1] + b[2] * X[2] * M[2] + b[3] * X[3] * M[3]) % N, N);
                break;

        }

    free(a);
    free(b);
    free(n);
    free(M);
    free(X);

    return 0;
}
}

Questao 10

Desenvolver um código que calcule a criptografia RSA, no qual o

usuário irá definir os primos (p e q) , número E e o tamanho do

bloco. Definir um pré-código com o alfabeto iniciando em A =11, como

mostrado em aula (linguagens C ou C++)

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

int MDC(int num1, int num2) {
    int aux;
    if (num1 % num2 == 0)
        return num2;
    else {
        aux = num2;
        num2 = num1 % num2;
        num1 = aux;
        return MDC(num1, num2);
    }
}

int inverso(int e, int z) {
    int inverso = 1;
    while ((e * inverso) % z != 1) {
        inverso++;
    }
    return inverso;
}

int mapearCaractere(char c) {
    if (c >= 'A' && c <= 'Z')
        return c - 'A' + 11;
    else if (c == ' ')
        return 99;
    else
        return -1;
}

void converterParaBlocos(char mensagem[], int tamBloco, int blocos[], int *qtdBlocos) {
    int i, num, pos = 0;
    char blocoAtual[256] = "";

    for (i = 0; mensagem[i] != '\0'; i++) {
        num = mapearCaractere(mensagem[i]);
        if (num == -1) {
            printf("Caractere inválido na mensagem: '%c'\n", mensagem[i]);
            continue;
        }

        char temp[10];
        sprintf(temp, "%d", num);
        strcat(blocoAtual, temp);

        if ((i + 1) % tamBloco == 0 || mensagem[i + 1] == '\0') {
            blocos[pos++] = atoi(blocoAtual);
            blocoAtual[0] = '\0';
        }
    }
    *qtdBlocos = pos;
}

int criptografar(int m, int e, int n) {
    long long resultado = 1;
    for (int i = 0; i < e; i++) {
        resultado = (resultado * m) % n;
    }
    return (int)resultado;
}

int descriptografar(int c, int d, int n) {
    long long resultado = 1;
    for (int i = 0; i < d; i++) {
        resultado = (resultado * c) % n;
    }
    return (int)resultado;
}

int main() {
    int p, q, e, tamBloco, blocos[256], qtdBlocos;
    char mensagem[256];

    printf("\nDigite um numero p primo: ");
    scanf("%d", &p);
    printf("\nDigite um numero q primo: ");
    scanf("%d", &q);

    int n = p * q;
    int z = (p - 1) * (q - 1);

    printf("\nDigite o valor de e: ");
    scanf("%d", &e);

    if (e > n || e > z || MDC(e, z) != 1) {
        printf("Valor de e invalido. \n");
        printf("e deve ser menor que n, menor que z e mdc(e, z) = 1");
        return 0;
    }

    printf("\nDigite o tamanho do bloco: ");
    scanf("%d", &tamBloco);

    int d = inverso(e, z);

    printf("\nDigite uma mensagem: ");
    scanf(" %[^\n]", mensagem);

    memset(blocos, 0, sizeof(blocos));
    converterParaBlocos(mensagem, tamBloco, blocos, &qtdBlocos);

    printf("\nBlocos gerados:\n");
    for (int i = 0; i < qtdBlocos; i++) {
        printf("Bloco %d: %d\n", i + 1, blocos[i]);
    }

    printf("\nBlocos criptografados:\n");
    int blocosCriptografados[256];
    for (int i = 0; i < qtdBlocos; i++) {
        blocosCriptografados[i] = criptografar(blocos[i], e, n);
        printf("Bloco %d: %d\n", i + 1, blocosCriptografados[i]);
    }

    printf("\nBlocos descriptografados:\n");
    for (int i = 0; i < qtdBlocos; i++) {
        int blocoOriginal = descriptografar(blocosCriptografados[i], d, n);
        printf("Bloco %d: %d\n", i + 1, blocoOriginal);
    }

    return 0;
}

##Questao 11

Desenvolver um código que calcule o CPF e o ISBN de um livro,

utilizando as regras de congruência (linguagens C ou C++)

codigo verificador de cpf

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

int verificaDigito10(char cpf[]){
    int verifica = 0;

    for(int i = 0; i < 9; i++){
        verifica += (cpf[i] - '0') * (10 - i);
    }

    int resto = verifica % 11;
    int digito10 = (resto < 2) ? 0 : (11 - resto);


    if(digito10 == (cpf[9] - '0')){
        return 1;
    }else{
        return 0;
    }

}

int verificaDigito11(char cpf[]){
    int verifica = 0;

    for(int i = 0; i < 10; i++){
        verifica += (cpf[i] - '0') * (11 - i);
    }

    int resto = verifica % 11;
    int digito11 = (resto < 2) ? 0 : (11 - resto);

    if(digito11 == (cpf[10] - '0')){
        return 1;
    }else{
        return 0;
    }

}

void verificaCPF(char cpf[]){
    if(verificaDigito10(cpf) == 1 && verificaDigito11(cpf) == 1){
        printf("\n CPF Valido \n");
    }else{
        printf("\n CPF Invalido \n");
    }
}

int main(){
    
    char cpf[12];

    printf("Insira um cpf (so numeros): ");
    scanf("%11s", cpf);

    verificaCPF(cpf);

}

codigo verificador de isbn

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

int verificaDigito10(char isbn[]){
    int verifica = 0;

    for(int i = 0; i < 9; i++){
        verifica += (isbn[i] - '0') * (10 - i);
    }

    int resto = verifica % 11;
    if(verifica == 10){
        if(isbn[9] == 'x'){
            return 1;
        }else{
            return 0;
        }
    }

    if (resto == (isbn[9] - '0')){
        return 1;
    }else{
        return 0;
    }

}

int main(){
    
    char isbn[10];

    printf("Insira um isbn (so numeros): ");
    scanf("%10s", isbn);

    if(verificaDigito10(isbn) == 1){
        printf("\n Isbn Valido \n");
    }else{
        printf("\n Isbn Invalido \n");
    }

}