Cifrado de vigenere en c -- beginner campo con c campo con vigenere-cipher camp codereview Relacionados El problema

Vigenere's Cipher in C


4
vote

problema

Español

He actualizado el código y el programa ahora funciona como debería. Si pudieras criticar mi código que sería genial. Soy nuevo en C, así que supongo que habré hecho algún error de novato :)

  #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdbool.h>  // Function to check if alphabet characters. int alphaCheck(char * argv[]) {   int length = strlen(argv[1]), n;   for (n = 0; n < length; n++) {     if (!isalpha(argv[1][n])) {       printf("Characters 'A-Z' for Keyword. ");       return 2;     }   } }  int main(int argc, char * keyWord[]) {   int cipher[64], i, j, k;   char message[128];   int keyCount = 0;   int p = strlen(keyWord[1]);    // Validation - using alphaCheck Function   if (argc != 2 || alphaCheck(keyWord) == 2) {     return 0;   }    // For loop to convert to upper and set value ie A = 0 B = 1   for (i = 0, j = strlen(keyWord[1]); i < j; i++) {     cipher[i] = (toupper(keyWord[1][i]) - 65);   }    // Prompt the user for the message to encrypt   printf("Enter your secret message: ");   fgets(message, 128, stdin);    for (i = 0, k = strlen(message); i < k; i++) {     if (isupper(message[i])) {       char c = (message[i] - 65 + cipher[keyCount])  % 26 + 65;       printf("%c", c);       keyCount++;     }     else if (islower(message[i])) {       char d = (message[i] - 97 + cipher[keyCount]) % 26 + 97;       printf("%c", d);       keyCount++;     }     else {       printf("%c ", message[i]);     }     if (keyCount >= p) {       keyCount = 0;     }   } }   
Original en ingles

I have updated the code and the program now works as it should. If you could critique my code that would be great. I am new to C so I guess I will have made some rookie error :)

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <stdbool.h>  // Function to check if alphabet characters. int alphaCheck(char * argv[]) {   int length = strlen(argv[1]), n;   for (n = 0; n < length; n++) {     if (!isalpha(argv[1][n])) {       printf("Characters 'A-Z' for Keyword.\n");       return 2;     }   } }  int main(int argc, char * keyWord[]) {   int cipher[64], i, j, k;   char message[128];   int keyCount = 0;   int p = strlen(keyWord[1]);    // Validation - using alphaCheck Function   if (argc != 2 || alphaCheck(keyWord) == 2) {     return 0;   }    // For loop to convert to upper and set value ie A = 0 B = 1   for (i = 0, j = strlen(keyWord[1]); i < j; i++) {     cipher[i] = (toupper(keyWord[1][i]) - 65);   }    // Prompt the user for the message to encrypt   printf("Enter your secret message: ");   fgets(message, 128, stdin);    for (i = 0, k = strlen(message); i < k; i++) {     if (isupper(message[i])) {       char c = (message[i] - 65 + cipher[keyCount])  % 26 + 65;       printf("%c", c);       keyCount++;     }     else if (islower(message[i])) {       char d = (message[i] - 97 + cipher[keyCount]) % 26 + 97;       printf("%c", d);       keyCount++;     }     else {       printf("%c\n", message[i]);     }     if (keyCount >= p) {       keyCount = 0;     }   } } 
        

Lista de respuestas

2
 
vote

i++ o ++i ?

Uso i++ está bien aquí, pero también lee esta discusión:

https://stackoverflow.com//stions/4261708/i-Or-i -in-for-bucles

fgets(message, 128, stdin);

¿Qué tal typeof0 - hace que sea más fácil cambiar el tamaño del typeof1 búfer.

typeof2

La mayoría de las personas están acostumbradas a ver:

  typeof3  

typeof4

¿Qué tal:

  typeof5  

En primer lugar, esto hace typeof6 utilizable en cualquier cadena, no solo 99887766555443317 . También evitas la computación de la longitud de la cadena. Además, esta es la forma idiomática de iterar sobre una cadena terminada por nula en c.

Finalmente: asegúrese de que siempre devuelva un valor, ya que ha declarado que esta función devuelve un 99887776655443318 .

typeof9

Está modificando #define ABS(x) ((x) > 0 ? x : -x) 0 , ¿pero está comprobando que #define ABS(x) ((x) > 0 ? x : -x) 1 ? ¿Qué pasa si #define ABS(x) ((x) > 0 ? x : -x) 2 tiene longitud y gt; 64?

#define ABS(x) ((x) > 0 ? x : -x) 3

Usted hace referencia a este elemento de matriz muchas veces en el programa. Tal vez usted debe asignar un nombre de variable significativo, por ejemplo:

  #define ABS(x) ((x) > 0 ? x : -x) 4  

Te hará que el programa sea más legible.

#define ABS(x) ((x) > 0 ? x : -x) 5

¿Desea volver a imprimir un #define ABS(x) ((x) > 0 ? x : -x) 6 aquí? Pensaría que solo quiere imprimir un 99887766555443327 al final del mensaje.

El bucle principal

Usted principal bucle tiene esta estructura:

  #define ABS(x) ((x) > 0 ? x : -x) 8  

Sería bueno si el código pudiera coincidir con esto lo más posible.

¿Qué tal:

  #define ABS(x) ((x) > 0 ? x : -x) 9  

Ahora solo hay un lugar donde se imprime el carácter cifrado, en lugar de tres lugares de diferencia.

Puede implementar esto a través de una función de ayuda:

  <math.h>0  

Sugerencia: la expresión <math.h>1 podría ser útil aquí.

 

i++ or ++i?

Using i++ is fine here, but also read this discussion:

https://stackoverflow.com/questions/4261708/i-or-i-in-for-loops

fgets(message, 128, stdin);

How about fget(message, sizeof(message), stdin) -- makes it easier to change the size of the message buffer.

int main(int argc, char * keyWord[])

Most people are used to seeing:

int main(int argc, char* argv[]) 

int alphaCheck(char * argv[])

How about:

int alphaCheck(char *str) {   for ( ;*str; ++str) {     if (!isalpha(*str)) {       ...     }   }   return 0;   // You don't have this return. } 

First of all, this makes alphaCheck usable on any string, not just argv[1]. Also you avoid computing the length of the string. Moreover, this is the idiomatic way to iterate over a null-terminated string in C.

Finally - make sure you always return a value since you've declared this function returns an int.

for (i = 0, j = strlen(keyWord[1]); i < j; i++) {

You are modifying cipher[i] but are you checking that i < 64? What if keyWord[1] has length > 64?

keyWord[1]

You reference this array element many times in the program. Perhaps you should assign a meaningful variable name to it, e.g.:

char* secret = keyWord[1]; 

It will make you program more readable.

printf("%c\n", message[i]);

Do you want to always print a \n here? I would think you only want to print an extra \n at the end of the message.

the main loop

You main loop has this structure:

for each character c in the message:   let e = encrypt c using the secret key   printf("%c", e)   advance pointers, counters, etc. printf("\n") 

so it would be nice if the code could match this as much as possible.

How about:

int i; for (char *p = message, i = 0; *p; ++p, ++i) {   char e = ...encrypt (*p) using secret, strlen(secret) and i...   printf("%c", e); } printf("\n"); 

Now there is only one place where the encrypted character is printed out - instead of three difference places.

You can implement this via a helper function:

char encrypt(char* secret, int secret_len, char c, int i) {   // return how c is encrypted when at position i in the message.   if (isupper(c)) {     return ...   } else if (islower(c)) {     return ...   } else {     return c;   } } 

Hint: The expression i % secret_len might come in handy here.

 
 
 
 
0
 
vote

Declaraciones

    int length = strlen(argv[1]), n;   

En general, es preferible poner una sola declaración en una línea donde realiza una tarea. Así que digamos

    int length = strlen(argv[1]);   int n;   

o

    int length, n;   length = strlen(argv[1]);   

de cualquier manera puede funcionar. Me gusta más el primero. Lo único que yo diría es que me gusta tener la declaración y la inicialización en la misma línea. No encuentro que las declaraciones se vinculen entre sí tanto como la inicialización está vinculada a la Declaración.

Convenciones de nombres

tienes

    for (n = 0; n < length; n++) {   

y

    for (i = 0, j = strlen(keyWord[1]); i < j; i++) {   

Como convención, i , j , y k son variables de índice y 99887776655443388 , m , y int length = strlen(argv[1]); int n; 0 son variables de límite. Entonces, la primera línea anterior usaría int length = strlen(argv[1]); int n; 1 en lugar de int length = strlen(argv[1]); int n; 2 y el segundo se volvería

    int length = strlen(argv[1]);   int n; 3  

Tenga en cuenta que esta es una convención puramente. No hay razón funcional para esto.

Números mágicos

    int length = strlen(argv[1]);   int n; 4  

Evite los usos repetidos de los números descubiertos (a menudo se llama Números mágicos ). En lugar de definir constantes. El CAY ORIGINAL C fue

    int length = strlen(argv[1]);   int n; 5  

que usarías

    int length = strlen(argv[1]);   int n; 6  

De esta manera, puede cambiar el valor en un solo lugar y tenerlo afecta a muchos lugares.

Tenga en cuenta que los compiladores de C modernos generalmente manejarán la misma sintaxis que los usos C ++ para constantes. Aunque estoy menos familiarizado con eso.

    int length = strlen(argv[1]);   int n; 7  

Consideraría este caso especial de un número mágico. Pero no necesitas definir una constante para ello. Solo diga

    int length = strlen(argv[1]);   int n; 8  

Más tarde,

    int length = strlen(argv[1]);   int n; 9  

puede convertirse

    int length, n;   length = strlen(argv[1]); 0  

Tenga en cuenta que podría argumentar que int length, n; length = strlen(argv[1]); 1 nunca cambiará. Pero otra razón para definir constantes es que actúan como comentarios. Ahora no tengo que pensar en qué significa o busque un comentario ". 99887766555443322 La fórmula lee más naturalmente con la constante.

 

Declarations

  int length = strlen(argv[1]), n; 

In general, it's preferable to put only one declaration in a line where you do an assignment. So either say

  int length = strlen(argv[1]);   int n; 

or

  int length, n;   length = strlen(argv[1]); 

Either way can work. I like the first one better. The only thing that I'd say is that I like having the declaration and the initialization on the same line. I don't find the declarations to be tied to each other as much as the initialization is tied to the declaration.

Naming Conventions

You have

  for (n = 0; n < length; n++) { 

and

  for (i = 0, j = strlen(keyWord[1]); i < j; i++) { 

As a convention, i, j, and k are index variables and n, m, and l are limit variables. So the first line above would use i instead of n and the second would become

  for (i = 0, n = strlen(keyWord[1]); i < n; i++) { 

Note that this is purely a convention. There's no functional reason for this.

Magic Numbers

  char message[128]; 

Avoid repeated uses of bare numbers (often called magic numbers). Instead define constants. The original C way was

#define MESSAGE_LENGTH 128 

which you'd use

  char message[MESSAGE_LENGTH]; 

This way you can change the value in just one place and have it affect many places.

Note that modern C compilers will generally handle the same syntax as C++ uses for constants. I'm less familiar with that though.

    cipher[i] = (toupper(keyWord[1][i]) - 65); 

I would consider this a special case of a magic number. But you don't need to define a constant for it. Just say

    cipher[i] = (toupper(keyWord[1][i]) - 'A'); 

Later,

      char d = (message[i] - 97 + cipher[keyCount]) % 26 + 97; 

can become

      char d = (message[i] - 'a' + cipher[keyCount]) % ALPHABET_SIZE + 'a'; 

Note that you could argue that 26 will never change. But another reason to define constants is that they act as comments. Now I don't have to think about what 26 means or look for a comment. The formula reads more naturally with the constant.

 
 
 
 

Relacionados problema

2  Cifrado y descifrado utilizando cambios alfabéticos  ( Encryption and decryption using alphabetic shifts ) 
Mi primera pieza de código cifra texto moviendo cada letra en la cadena 5 letras en el alfabeto. encrypt = input('Enter text to encrypt : ') encrypt = encr...

2  Cryptor c vigenere  ( C vigenere encryptor ) 
Este código está probado y funciona correctamente, estoy buscando algunos comentarios sobre las siguientes funciones. Bastante recto y simple, pero si se dese...

3  Vigenere cuadrado cypher descifrado  ( Vigenere square cypher decryption ) 
Estoy en el proceso de aprendizaje de Python y programó este ejercicio para descifrar el Plaza de Vigenere Cypher como práctica. Por favor comente las mej...

5  Vigenère cifrado en Ruby  ( Vigen%c3%a8re cipher in ruby ) 
lo que estoy tratando de hacer: implementar el cifrado de Vigenère en Ruby. Ya tengo una versión de trabajo, pero quiero asegurarme de que sea eficiente y b...

4  Programa CS50 Vigenere  ( Cs50 vigenere program ) 
Escribí un programa para un problema en el curso CS50 de Harvard, Vigenere (semana 2). Aquí hay una Descripción de lo que el programa necesita hacer : D...

2  Vigenère cifrado como filtro IO  ( Vigen%c3%a8re cipher as an io filter ) 
Implementé una clase de codificación y decodificación de Vigenere. Idealmente, el programa debería poder tomar cualquier archivo de abritry, lea en una matriz...

9  Vigenere Decyphir en C ++  ( Vigenere decypher in c ) 
He escrito un declador de Vigenere y me gustaría tener algunas opiniones antes de intentar refactorizarlo en más estilo OOP con clases y demás. gameKey()8 ...

6  Cipher de Vigenere - ¡Hacer código más conciso?  ( Vigenere cipher make code more concise ) 
Soy un principiante en la programación en general, comenzó hace aproximadamente un mes y, por ejemplo, todavía estoy tratando de hacerlo totalmente tallado de...

5  Cracking Vigenere y Caesar Texto cifrado en Python  ( Cracking vigenere and caesar ciphered text in python ) 
He escrito un par de programas en Python que se puede usar para cifrar, descifrar y crack Caesar y Vigenere cifró texto. Soy bastante nuevo en Python y escrib...

4  Caja de herramientas clásica de criptografía: CEESAR, VIGENERE y CIPHERS DE ADFGVX  ( Classic cryptography toolbox caesar vigenere and adfgvx ciphers ) 
Escribí un programa en Haskell que tiene como objetivo dejar que el usuario cifre, descifrar y crack / cryptanalyse pre-electromecánica era cifras en Haskell....




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos