• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Briooosa

Encriptar dados

21 mensagens neste tópico

boas,estou a tentar resolver uma pergunta de um exame de PC2,e não percebo como faço isto,

-escreva uma função que permita incriptar dados.

-a função recebe uma string como parametro e deve pedir uma password ao utilizador.

-o algoritmo de incriptação dos dados consiste em somar 1 ao código de todos os caracteres da string parametro e e colocar a password no fim da string obtida.

podem dar-me uma luz sobre como se faz isto?

obrigado

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Basicamente percorres todos os caracteres da string, e somas o 1 a cada caracter. A string resultante vai estar encriptada.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

como assim é só isto:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define max 5


void incripta(char string[max])
{


char pass[max];
int i=0;

for (i=0;i<max;i++)

string[i]=string[i+1];

printf("introduza uma password\n");
scanf("%s",&pass);

strcat (string,pass); //colocar a password no fim da string obtida
printf("%s",string);
}
}

esta a dar erro onde somo 1 ao caracter da string

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não, é assim, mesmo:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define max 5


void incripta(char string[max])
{


char pass[max];
int i=0;

for (i=0;i<max;i++)

string[i]++;

printf("introduza uma password\n");
scanf("%s",&pass);

strcat (string,pass); //colocar a password no fim da string obtida
printf("%s",string);
}
}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Essa deve ser a cifra mais estúpida que existe...

Pede a password e não a usa? E depois ainda a coloca no fim do criptograma?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Bem visto... eu só dei uma vista de olhos no código, mas agora q vejo melhor, para que raio está aí a pass? :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não, é assim, mesmo:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#define max 5


void incripta(char string[max])
{


char pass[max];
int i=0;

for (i=0;i<max;i++)

string[i]++;

printf("introduza uma password\n");
scanf("%s",&pass);

strcat (string,pass); //colocar a password no fim da string obtida
printf("%s",string);
}
}

Sim, deverá ser assim mas assim não funciona.

Há ai vários erros. Mas o 'mais escondido' é talvez o 'strcat'. Penso que antes de usarmos essa função temos de usar primeiro o 'strcpy'. Ainda não consegui perceber muito bem porquê...deve ter algo a ver com apontadores, mas ainda não consegui chegar lá...(se alguém souber explicar)

Experimenta assim:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define str_size 20
#define pass_size 10

void incripta(char myString[str_size]){
char str[str_size]; //declarar uma nova string
strcpy(str, myString); //copiar a string recebida para a nossa string

char pass[pass_size]; //password
int max = strlen(str); //número máximo de caracteres na string

int i=0;
for(i=0;i<max;i++) //incrementar uma vez o código ASCII de todos os caracteres na string
	str[i]++;

printf("introduza uma password\n"); //ler a password
scanf("%s",pass);


strcat(str,pass); //colocar a password no fim da string obtida
puts(str); //mostrar resultado
}

int main(){
incripta("testafuncao"); //chamar a função
return 0;
}

Ou um pouco mais optimizado:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define pass_size 10

void incripta(char * myString){
        char * str = (char*) malloc(sizeof(char)*(strlen(myString)+1)); //alocar espaço em memória
strcpy(str, myString); //copiar a string recebida para a nossa string

char pass[pass_size]; //password
int max = strlen(str); //número máximo de caracteres na string

int i=0;
for(i=0;i<max;i++) //incrementar uma vez o código ASCII de todos os caracteres na string
	str[i]++;

printf("introduza uma password\n"); //ler a password
scanf("%s",pass);


strcat(str,pass); //colocar a password no fim da string obtida
puts(str); //mostrar resultado
}

int main(){
incripta("testafuncao"); //chamar a função
return 0;
}

@Briooosa, aquilo que estavas a fazer inicialmente era a substituir o caracter actual da string pelo próximo. Neste caso, está a ser somado 1 ao código ASCII do caracter actual, ou seja, a seguir ao 't' vem o 'u', a seguir ao 'e' vem o 'f', e por ai adiante.

Espero ter ajudado.

Cumprimentos

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

obrigado,sinceramente nao tinhamos feito nada deste genero nas aulas,em relação ao tipo de pergunta,com strings até fizemos qq coisa.

nao estava a ver nada disto.

obrigado pelo esclarecimento,ja pode calhar no exame  amanha.

abraço

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sim, deverá ser assim mas assim não funciona.

Funciona. Não podes é chamar a função da maneira que chamas no teu código.

Há ai vários erros. Mas o 'mais escondido' é talvez o 'strcat'. Penso que antes de usarmos essa função temos de usar primeiro o 'strcpy'. Ainda não consegui perceber muito bem porquê...deve ter algo a ver com apontadores, mas ainda não consegui chegar lá...(se alguém souber explicar)

Tem a ver com o que disse acima. Ao chamares a função passando como parâmetro um array de char constante (como no teu exemplo, "testafuncao"), tens que copiar o seu conteúdo para outro array. Isto porque a string é definida no código, e é imutável, sendo passado um apontador para uma secção da memória que não pode ser alterada (isto não é 100% verdade, mas para o caso pode ser considerado assim).

No entanto, se passares um array à função, do seguinte modo:

char ca[str_size] = "testafuncao";
encripta(ca);

verás que já não precisas de utilizar o strcpy, porque o array já referencia uma zona de memória que pode ser escrita. No entanto, é sempre melhor utilizar a tua estratégia para evitar dissabores.

Tens vários problemas no código, sendo o 1º que ao fazer strcpy ali no meio da declaração das variáveis, estás a programar à C++. Em C tens que declarar as variáveis todas seguidas. E os comentários de uma linha também só existem em C++, em C só /* deste tipo */ .

Além disso, em ambas as versões estás a declarar espaço a menos para os arrays. Se a soma do tamanho da string passada à função com o tamanho da password for maior que str_size, vai ocorrer corrupção de memória. Resolve-se alocando espaço para o array depois de obter a password.

Se calhar o código que apresento de seguida é um bocado overkill em termos de segurança, mas é do hábito... :P

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define pass_size 100	/* Exagerar no tamanho da password para minimizar
					   a possibilidade de não ser toda lida */

char *cifra(char myString[]){
char *new_str = NULL,	/* Apontador que apontará para a nova string */
	pass[pass_size],	/* Mesmo que tenha muito espaço, este será
						   libertado no final da função */
	format[15];			/* para formatar a string com o número
						   máximo correcto de caracteres da password */
int i=0, j=0;

sprintf(format, "%%%ds", pass_size-1);	/* format fica com "%99s" */
printf("Introduza uma password: "); 
scanf(format, pass);	/* ler password com no máximo 99 caracteres */

new_str = (char*)malloc(sizeof(char)*(strlen(myString)*strlen(pass)+1));

/* Copiar todos os caracteres da string passada como parâmentro para
   new_str, e simultaneamente incrementá-los */
while (myString[i] != '\0') {		/* Quase o mesmo que strcpy	*/
	new_str[i] = myString[i++]+1;	/* mas com incremento		*/
}

//new_str[i] = '\0';				/* Ou se utilizam estas duas linhas	*/
//strcat(new_str, pass);			/* ou as três abaixo		*/

while (pass[j] != '\0')				/* Quase o mesmo que strcat		*/
	new_str[i++] = pass[j++];		/* mas um pouco mais eficiente	*/
new_str[i] = '\0';					/* porque não percorrer new_str	*/

return new_str;
}

int main(){
char *s = cifra("testafuncao");
printf("%s\n\n", s);
return 0;
}

De qualquer forma, não se põem os problemas de que falaste, nem os de corrupção de memória. E também não há buffer overrun na variável pass.

Será que me escapou alguma coisa...? ::D

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Funciona. Não podes é chamar a função da maneira que chamas no teu código.

Eu disse que não funcionava porque tinha vários erros, sendo alguns deles nos 'includes' :P

Tem a ver com o que disse acima. Ao chamares a função passando como parâmetro um array de char constante (como no teu exemplo, "testafuncao"), tens que copiar o seu conteúdo para outro array. Isto porque a string é definida no código, e é imutável, sendo passado um apontador para uma secção da memória que não pode ser alterada (isto não é 100% verdade, mas para o caso pode ser considerado assim).

No entanto, se passares um array à função, do seguinte modo:

char ca[str_size] = "testafuncao";
encripta(ca);

verás que já não precisas de utilizar o strcpy, porque o array já referencia uma zona de memória que pode ser escrita. No entanto, é sempre melhor utilizar a tua estratégia para evitar dissabores.

Pois, eu calculei que tivesse a ver com a alocação de espaço, daí termos de fazer o strcpy, mas não estava a perceber porquê. :)

Tens vários problemas no código, sendo o 1º que ao fazer strcpy ali no meio da declaração das variáveis, estás a programar à C++. Em C tens que declarar as variáveis todas seguidas.

Pois...disso eu tenho conhecimento mas estou habituado a declará-las quando me convém. Isso de ter de declará-las no início faz-me alguma confusão...talvez seja do hábito.

E os comentários de uma linha também só existem em C++, em C só /* deste tipo */ .

Isto não fazia ideia. Sempre usei '\\' e '/**/', inclusive na faculdade. Não sabia que em C só existia '/**/'.

Além disso, em ambas as versões estás a declarar espaço a menos para os arrays. Se a soma do tamanho da string passada à função com o tamanho da password for maior que str_size, vai ocorrer corrupção de memória. Resolve-se alocando espaço para o array depois de obter a password.

Pois...isso passou-me ao lado. Não me lembrei desse pormenor. Também não investi muito tempo nisso :D

Se calhar o código que apresento de seguida é um bocado overkill em termos de segurança, mas é do hábito... :P

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define pass_size 100	/* Exagerar no tamanho da password para minimizar
					   a possibilidade de não ser toda lida */

char *cifra(char myString[]){
char *new_str = NULL,	/* Apontador que apontará para a nova string */
	pass[pass_size],	/* Mesmo que tenha muito espaço, este será
						   libertado no final da função */
	format[15];			/* para formatar a string com o número
						   máximo correcto de caracteres da password */
int i=0, j=0;

sprintf(format, "%%%ds", pass_size-1);	/* format fica com "%99s" */
printf("Introduza uma password: "); 
scanf(format, pass);	/* ler password com no máximo 99 caracteres */

new_str = (char*)malloc(sizeof(char)*(strlen(myString)*strlen(pass)+1));

/* Copiar todos os caracteres da string passada como parâmentro para
   new_str, e simultaneamente incrementá-los */
while (myString[i] != '\0') {		/* Quase o mesmo que strcpy	*/
	new_str[i] = myString[i++]+1;	/* mas com incremento		*/
}

//new_str[i] = '\0';				/* Ou se utilizam estas duas linhas	*/
//strcat(new_str, pass);			/* ou as três abaixo		*/

while (pass[j] != '\0')				/* Quase o mesmo que strcat		*/
	new_str[i++] = pass[j++];		/* mas um pouco mais eficiente	*/
new_str[i] = '\0';					/* porque não percorrer new_str	*/

return new_str;
}

int main(){
char *s = cifra("testafuncao");
printf("%s\n\n", s);
return 0;
}

Um pouco mais confuso sim, agora tenho dir jantar mas mais logo a ver se percebo bem isso.

Só uma coisa...quando estou a receber arrays como parametros, gosto de usar sempre um apontador (como fiz no meu 2º código), em vez de copiar a string...Eu sei que neste caso é indiferente, mas noutros casos pode fazer alguma diferença...ou não?

Cumprimentos :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

E os comentários de uma linha também só existem em C++, em C só /* deste tipo */ .

Isso não é totalmente verdade... O C99, que é o último standard, já suporte esse tipo de comentários.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eu disse que não funcionava porque tinha vários erros, sendo alguns deles nos 'includes' :P

Hehe, nem olhei para os includes... Tens razão sim senhor.

Só uma coisa...quando estou a receber arrays como parametros, gosto de usar sempre um apontador (como fiz no meu 2º código), em vez de copiar a string...Eu sei que neste caso é indiferente, mas noutros casos pode fazer alguma diferença...ou não?

Copiar a string? Como assim? Não sei se percebi, mas, tanto quanto sei, teres char* ca ou char ca[] como parâmetro de uma função é semanticamente igual.

Isso não é totalmente verdade... O C99, que é o último standard, já suporte esse tipo de comentários.

Haha, modernices... eu sou um gajo antiquado. Não, a sério, não sabia disso!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Copiar a string? Como assim? Não sei se percebi, mas, tanto quanto sei, teres char* ca ou char ca[] como parâmetro de uma função é semanticamente igual.

char* ca é o mesmo que char ca[] ? São ambos um apontador para um array de cararcteres?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sim, a única coisa que é passada em ambos os casos é o endereço, em nenhum dos casos há cópia dos caracteres.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Sim, a única coisa que é passada em ambos os casos é o endereço, em nenhum dos casos há cópia dos caracteres.

Não sabia. Pensava que char str[] era mesmo um array e nao um apontador.

Cumps

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não sabia. Pensava que char str[] era mesmo um array e nao um apontador.

Um array é um apontador...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Um array é um apontador...

Sim tens razão...eu agora estava a fazer confusão. Eu estava a pensar num apontador (char* str) a apontar para uma posição de memória que seria o array, o que não é verdade. O uso de apontadores ('ou de arrays 'sem limite' como char str[]'), a única vantagem que têm (neste caso) é que não alocam espaço desnecessário em memória quando copiamos o array.

Eu estava-me a baralhar e estava a pensar num apontador como que a apontar para os caracteres na memória, sem necessidade de cópia. Mas de qualquer maneira temos sempre de alocar espaço.

Peço desculpa :P

(Não sei se me fiz entender...)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Um array é um apontador...

É a msm coisa ou são coisas diferentes tratadas e interpretadas pelo compilador de igual modo?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É a msm coisa ou são coisas diferentes tratadas e interpretadas pelo compilador de igual modo?

São coisas diferentes. Um apontador contém um endereço de memória, enquanto que um array contém uma lista de elementos que ocupam posições contíguas de memória. O que ele queria dizer é que o nome de um array funciona como um apontador para o mesmo,  uma vez que é um apontador para o seu primeiro elemento. Seja v um array: v == &v[0].

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Em termos práticos, um array é um apontador (no entanto, um apontador não é necessariamente um array). Podemos declarar um array como um apontador, e aceder a ele como sendo um array.

Pensem em quando usam um char*. Embora isto possa ser um apontador para um caracter, normalmente, uma variável declarada com este tipo trata-se de uma string, e uma string em C é uma array de caracteres.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Se calhar o código que apresento de seguida é um bocado overkill em termos de segurança, mas é do hábito... :P

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define pass_size 100	/* Exagerar no tamanho da password para minimizar
					   a possibilidade de não ser toda lida */

char *cifra(char myString[]){
char *new_str = NULL,	/* Apontador que apontará para a nova string */
	pass[pass_size],	/* Mesmo que tenha muito espaço, este será
						   libertado no final da função */
	format[15];			/* para formatar a string com o número
						   máximo correcto de caracteres da password */
int i=0, j=0;

sprintf(format, "%%%ds", pass_size-1);	/* format fica com "%99s" */
printf("Introduza uma password: ");
scanf(format, pass);	/* ler password com no máximo 99 caracteres */

new_str = (char*)malloc(sizeof(char)*(strlen(myString)*strlen(pass)+1));

/* Copiar todos os caracteres da string passada como parâmentro para
   new_str, e simultaneamente incrementá-los */
while (myString[i] != '\0') {		/* Quase o mesmo que strcpy	*/
	new_str[i] = myString[i++]+1;	/* mas com incremento		*/
}

//new_str[i] = '\0';				/* Ou se utilizam estas duas linhas	*/
//strcat(new_str, pass);			/* ou as três abaixo		*/

while (pass[j] != '\0')				/* Quase o mesmo que strcat		*/
	new_str[i++] = pass[j++];		/* mas um pouco mais eficiente	*/
new_str[i] = '\0';					/* porque não percorrer new_str	*/

return new_str;
}

int main(){
char *s = cifra("testafuncao");
printf("%s\n\n", s);
return 0;
}

boas! sou um novato quer no mundo da programação quer aqui no forum. tenho uma dúvida e isto pode fazer a diferença entre a positiva ou a negativa numa cadeira!!! se se tratar, em vez de uma string, de um vector com numeros inteiros (que já me são fornecidos), o que muda e como faço isto??

obrigado em avanço ;)

Editado por apocsantos
Correcção da tag [/quote]
0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora