Jump to content
Diogo Pereira

Codificação de mensagem

Recommended Posts

Diogo Pereira

Boas, eu sou ainda um bocado inexperiente com programação e tenho um problema para fazer no entanto nao consigo encontrar a resolução. O problema é o seguinte:

Citação

 

Um indivíduo desconfiado decidiu codificar as suas mensagens usando um esquema simples de codificação. Cada minúscula e cada maiúscula é substituída por outra com o código ASCII deslocado k unidades. Se a deslocação exceder o limite do alfabeto recomeça do início do mesmo. Os restantes carateres ficam inalterados.

Sugestão: Para não ter problemas com a o carater '\n' na primeira utilização do getchar use scanf("%d\n",&k);.

Sugestão: defina a função cifra e chame-a do programa principal.

Input

Um valor k entre 0 e 25, seguido de uma sequência de carateres terminada pelo carater mudança de linha.

Output

A codificação da sequência de carateres terminando com mudança de linha.

 

Para já o meu código encontra-se da seguinte maneira:

#include <stdio.h>

int maiscula (char c) {
    if (c>='A' && c<='Z')
        return 1;
    else
        return 0;
    }

int minuscula (char c) {
    if (c>='a' && c<='z')
        return 1;
    else 
        return 0;
    }

int main () {
    char c, nova;
    int k;
    scanf ("%d\n", &k);
    while (c!='\n') {
        scanf ("%c", &c);
        nova=c+k;
        if (maiscula(c)) {
                while (nova>'Z' || nova<'A') {
                k=nova-'Z';
                if (k==1) 
                nova='A';
                else {
                    c='A';
                    nova=c+k;
                }
        }
        }
        if (minuscula(c)) {
                while (nova>'z' || nova<'a') {
                k=nova-'z';
                if (k==1)
                nova='a';
                else {
                    c='a';
                    nova='a'+k;
                }
        }
    }
        printf ("%c", nova);
    }
    printf ("\n");
    return 0;
}

Gostaria de saber se podiam ajudar a descobrir o que esta mal ou então dar a sugestão de um código mais "limpo". 

Share this post


Link to post
Share on other sites
Diogo Pereira
15 horas atrás, HappyHippyHippo disse:

quanto é que é 20 + 20 <resto da divisão inteira> de 23 ?

22.. mas como e que isso me ajuda neste problema?

Share this post


Link to post
Share on other sites
HappyHippyHippo
7 minutes ago, Diogo Pereira said:

22.. mas como e que isso me ajuda neste problema?

primeiro, deixa-me corrigir a pergunta : (20 + 20) % 23

segundo, a resposta não é acertada para (20 + 20) % 23 nem para 20 + (20 % 23)

terceiro : quando acertares na resposta, a sua utilizade ficará mais evidente

  • Vote 1

IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Eu ainda não percebi bem o enunciado sequer...

Primeiro diz:

On quinta-feira, 17 de Novembro de 2016 at 9:50 PM, Diogo Pereira said:

Se a deslocação exceder o limite do alfabeto recomeça do início do mesmo.

Começar do início do mesmo??? Não percebo.

Será que por exemplo, se eu quiser "codificar" um 'z' e o K for 36 (considerando o alfabeto com 26 letras), significa substituir o 'z' pela 10ª letra do alfabeto e assim por diante?

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
HappyHippyHippo
55 minutes ago, PsySc0rpi0n said:

Eu ainda não percebi bem o enunciado sequer...

Primeiro diz:

Começar do início do mesmo??? Não percebo.

Será que por exemplo, se eu quiser "codificar" um 'z' e o K for 36 (considerando o alfabeto com 26 letras), significa substituir o 'z' pela 10ª letra do alfabeto e assim por diante?

z + k = final

26 + 36 = 62 ... hum 62 é bem mais do que o tamanho do alfabeto .... que fazer ?

talvez a dica está na pergunta que fiz anteriormente


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
PsySc0rpi0n
1 hour ago, HappyHippyHippo said:

z + k = final

26 + 36 = 62 ... hum 62 é bem mais do que o tamanho do alfabeto .... que fazer ?

talvez a dica está na pergunta que fiz anteriormente

Mas k não era um parâmetro pedido ao user? Fiquei com essa ideia...

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
HappyHippyHippo
16 minutes ago, PsySc0rpi0n said:

Mas k não era um parâmetro pedido ao user? Fiquei com essa ideia, até porque depois há uma nota que diz que o k varia entre 0 e 25...

irrelevante


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
PsySc0rpi0n
1 hour ago, HappyHippyHippo said:

irrelevante

Sim, mas em termos de código acaba por ser ligeiramente diferente, acho eu! Embora eu não esteja sequer a visualizar como seria o código porque não cheguei a percerber bem o problema!

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
Flinger

A única coisa diferente é a leitura do parâmetro, a função de codificação é igual.

A única coisa que me deixou um pouco confuso foi o Hippo ter usado o 23, e não o 26 :D  mas devem ser reminiscências da primária :P

Deixa-me dar uma dica, tens um array circular de 5 posições:

1 2 3 4 5

estás na posição 4 e queres andar 3 posições para a frente. Em que posição ficas?

Edited by Flinger

Share this post


Link to post
Share on other sites
PsySc0rpi0n
2 hours ago, Flinger said:

A única coisa diferente é a leitura do parâmetro, a função de codificação é igual.

A única coisa que me deixou um pouco confuso foi o Hippo ter usado o 23, e não o 26 :D  mas devem ser reminiscências da primária :P

Deixa-me dar uma dica, tens um array circular de 5 posições:

1 2 3 4 5

estás na posição 4 e queres andar 3 posições para a frente. Em que posição ficas?

Sim, eu percebi isso... O que me referia é que vendo as coisas como o @HappyHippyHippo estava a ver no post lá mais acima em que diz z + k = final -> 26 + 36 = 62 tem um código associado e vendo como eu estava a ver, que acho que é como tu estás a ver, que é que a codificação vai ter um offset de 'k' unidades, o código iria ser diferente. Ou seja:

 

0 1 2 3 4 5 6 ...... 24 25

^ ^ ^ ^ ^ ^ ^ ^........^    ^

a b c d e f g .........y   z

Para codificar a letra 'z' com um k = 36, O 'z' iria ser substituído por um 'k', porque é a letra que está na posição 36 - 26 = 10 do alfabeto.

Acho que esta interpretação não é a mesma que a que o @HappyHippyHippo fez lá atrás!

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
Flinger

O K não deveria ser maior que o alfabeto, mas com o método do Hippo, vai dar ao mesmo. O que vai acontecer é que vais "dar uma volta a mais". Mas aplicas o mesmo.

Seguindo o exemplo que te dei, por ser mais fácil, e aplicando a formula do Hippo:

( 4 + 3 ) % 5 = 2.

Se quiser andar 8 posições para a frente, tenho (4 + 8) % 5 = 2. O resultado é o mesmo. Logo para fazeres o K = 36 ou K = 10 no caso do alfabeto, é rigorosamente o mesmo. O resto da divisão é igual. 

Share this post


Link to post
Share on other sites
HappyHippyHippo

por outras palavras, tudo se resume ao meu primeiro post :

On ‎18‎/‎11‎/‎2016 at 1:43 AM, HappyHippyHippo said:

conheces o operador "resto da divisão inteira" ?

 


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Para ser honesto também não estou a perceber como é que o resto da divisão inteira vai fazer a codificação com um determinado offset respeitando o "comprimento" do alfabeto e voltando ao início. Ou então eu ainda não percebi bem o que era pretendido.

Mas eu tentei fazer um teste e não obtive nada de jeito.

Se eu tiver uma string e disser que o k=10, por exemplo, todas as letras que estejam a menos de 10 unidades da 26ª letra do alfabeto, serão codificadas com as letras do início do alfabeto, respectivamente.

O que eu fiz foi:

pString[i] = (pString[i] + k) % 26;
printf("Char: %c", pString[i]);

 

que me parece ter sido o que o @Flinger mas adaptado aqui ao caso do OP!

Isto foi apenas um exemplo que fiz para tentar perceber se as letras codificadas ficavam com o offset esperado!

 

O código que fiz para teste foi este:

#include <stdio.h>

int VerificaChar(char pcaracter){
	if((pcaracter >= 'A' && pcaracter <= 'Z') || (pcaracter >= 'a' && pcaracter <= 'z'))
		return 1;
	else
		return 0;
}

char* Encripta(char* pString, int pk){
	int i = 0;
	while(pString[i] != '\0'){
		if(VerificaChar(pString[i]))
			pString[i] = (pString[i++] + pk) % 26;
	}
}

int main(void) {
	// your code goes here
	char String[6] = "aaaaa";
	Encripta(String, 10);
	printf("Encriptada: %s\n", String);
	return 0;
}

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
Flinger

Só tens um problema com isso, é que funciona para um alfabeto codificado de 0 a 25. Os códigos ASCII dos caracteres não encaixam nessa codificação.

Ou seja não podes usar os caracteres ascii, tens de converter de ASCII para uma codificação tua, e depois de volta para ASCII.

Edited by Flinger
codificado entre "0 e 25" e não "1 e 26"

Share this post


Link to post
Share on other sites
PsySc0rpi0n

Sim, mas conforme está, nem num alfabeto codificado de 1 a 26 funciona, pois o output deste código é "nada", nada é imprimido no terminal! Pelo menos compilado e executado no site do ideone.com.

Edited by PsySc0rpi0n

Kurt Cobain - Grunge misses you

Nissan GT-R - beast killer

Share this post


Link to post
Share on other sites
Flinger

Qual é o valor do 'a'? E qual é o caracter que tem o código ('a' + 10) % 26 ?

 

De outra forma, seja qual for o caracter a codificar, o valor retornado pela codificação é sempre um valor entre 0 e 25... Consegues ver a que caracteres correspondem os códigos ascii entre 0 e 25?

Share this post


Link to post
Share on other sites
HappyHippyHippo

bem ... respondendo directamente ao post original :

#include <stdio.h>

#define alphabetSize ('z' - 'a')
#define isAlpha(pStr) (((* pStr) >= 'a' && (* pStr) <= 'z') || ((* pStr) >= 'A' && (* pStr) <= 'Z'))
#define shiftAmount(pStr) ((* pStr) >= 'a' && (* pStr) <= 'z' ? 'a' : 'A')

char * encripta(char * pStr, int pk) {
    while (* pStr) {
        if (isAlpha(pStr)) {
            unsigned char shift = shiftAmount(pStr);
            * pStr = (((* pStr - shift) + pk) % alphabetSize) + shift;
        }
        pStr++;
    }
    return pStr;
}

char * decripta(char * pStr, int pk) {
    while (* pStr) {
        if (isAlpha(pStr)) {
            unsigned char shift = shiftAmount(pStr);
            * pStr = (((* pStr - shift) + (alphabetSize - pk)) % alphabetSize) + shift;
        }
        pStr++;
    }
    return pStr;
}

int main (void) {
	char str[36] = "HappyHippyHippo does minimalist code";

	encripta(str, 10);
	printf("Encriptada: %s\n", str);

	decripta(str, 10);
	printf("Decriptada: %s\n", str);

	return 0;
}

 


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
Diogo Pereira

Desculpem, eu depois nao consegui vir aqui, mas eu ja tinha resolvido o problema. Obrigado por toda a ajuda e o modulo foi mesmo necessário :D .

Deixo aqui um código mais "simples":

#include <stdio.h>

int maiscula (char c) {
    if (c>='A' && c<='Z')
        return 1;
    else
        return 0;
    }

int minuscula (char c) {
    if (c>='a' && c<='z')
        return 1;
    else 
        return 0;
    }

int main () {
    char c, nova;
    int k;    
    scanf ("%d\n", &k);
    while (c!='\n') {
        scanf ("%c", &c);
        if (maiscula(c)) {
            nova=(c-'A'+k)%26+'A';
            printf ("%c", nova);
        }
        else if (minuscula(c)) {
            nova=(c-'a'+k)%26+'a';
            printf ("%c", nova);
        }
        else
            printf ("%c", c);
    }
    printf ("\n");
    
    return 0;
}

 

Edited by pwseo
bloco de código

Share this post


Link to post
Share on other sites
HappyHippyHippo

mais simples que o meu, que até tem o código de decriptação ?!?! blasfémia !!!!


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.