Advertisement
avr39ripe

cVigenereAdvanced

Mar 6th, 2021 (edited)
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.45 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <ctype.h>
  4.  
  5. int checkParams(const char* key, const char* text)
  6. {
  7.     if (!(text && key)) { return 0; }
  8.  
  9.     while (*key)
  10.     {
  11.         if (!isalpha(*key++)) { return 0; }
  12.     }
  13.     return 1;
  14. }
  15.  
  16. char* vigenere_encrypt(const char* key, const char* text)
  17. {
  18.     char* result = NULL;
  19.     // check if both text and key not NULL pointers
  20.     if (checkParams(key, text))
  21.     {
  22.         // this constant holds alphabet length, 26 for English
  23.         const int alphaLength = 26;
  24.         // allocate strlen(text) + 1 for '\0' and to be shure multiple to sizeof char :)
  25.         result = calloc(sizeof(char), strlen(text) + 1);
  26.         // copy pointer to allocated memory block to work with and modify
  27.         char* encrypt = result;
  28.         // get length of the key for "key-cycling"
  29.         size_t keyLength = strlen(key);
  30.         // position of next to use for encoding symbol from key
  31.         size_t keyPos = 0;
  32.  
  33.         while (*text)
  34.         {
  35.             // check if next symbol is letter, if so - encode, if no - just copy as is
  36.             if (isalpha(*text))
  37.             {
  38.                 // encrypt every symbol from original string by properly selected symbol from key
  39.                 *encrypt++ = ('A' + (toupper(*text++) + toupper(*(key + keyPos))) % alphaLength);
  40.                 // increase key symbol position
  41.                 ++keyPos;
  42.                 // cycle key symbol position
  43.                 keyPos %= keyLength;
  44.             }
  45.             else
  46.             {
  47.                 // just copy as is if not a letter
  48.                 *encrypt++ = *text++;
  49.             }
  50.  
  51.         }
  52.         // properly terminate encoded string with '\0'
  53.         *encrypt = '\0';
  54.     }
  55.     // return pointer to originally allocated memory block for encoded string or NULL
  56.     return result;
  57. }
  58.  
  59. char* vigenere_decrypt(const char* key, const char* text)
  60. {
  61.     char* result = NULL;
  62.     // check if both text and key not NULL pointers
  63.     if (checkParams(key, text))
  64.     {
  65.         // this constant holds alphabet length, 26 for English
  66.         const int alphaLength = 26;
  67.         // allocate strlen(text) + 1 for '\0' and to be shure multiple to sizeof char :)
  68.         result = calloc(sizeof(char), strlen(text) + 1);
  69.         // copy pointer to allocated memory block to work with and modify
  70.         char* decrypt = result;
  71.         // get length of the key for "key-cycling"
  72.         size_t keyLength = strlen(key);
  73.         // position of next to use for decoding symbol from key
  74.         size_t keyPos = 0;
  75.  
  76.         while (*text)
  77.         {
  78.             // check if next symbol is letter, if so - decode, if no - just copy as is
  79.             if (isalpha(*text))
  80.             {
  81.                 // decrypt every symbol from original string by properly selected symbol from key
  82.                 *decrypt++ = ('A' + (toupper(*text++) + alphaLength - toupper(*(key + keyPos))) % alphaLength);
  83.                 // increase key symbol position
  84.                 ++keyPos;
  85.                 // cycle key symbol position
  86.                 keyPos %= keyLength;
  87.             }
  88.             else
  89.             {
  90.                 // just copy as is if not a letter
  91.                 *decrypt++ = *text++;
  92.             }
  93.         }
  94.         // properly terminate decoded string with '\0'
  95.         *decrypt = '\0';
  96.     }
  97.     // return pointer to originally allocated memory block for decoded string or NULL
  98.     return result;
  99. }
  100.  
  101. // all-in-one version as a bonus ;) no comments :) mode = 1 -> encode, mode = 0 -> decode
  102. char* vigenere(const char* key, const char* text, int mode)
  103. {
  104.     char* result = NULL;
  105.     if (checkParams(key, text))
  106.     {
  107.         const int alphaLength = 26;
  108.         result = calloc(sizeof(char), strlen(text) + 1);
  109.         char* resText = result;
  110.         size_t keyLength = strlen(key);
  111.         size_t keyPos = 0;
  112.  
  113.         while (*text)
  114.         {
  115.             if (isalpha(*text))
  116.             {
  117.                 *resText++ = ('A' + (toupper(*text++) + (mode ? toupper(*(key + keyPos++)) : alphaLength - toupper(*(key + keyPos++)))) % alphaLength);
  118.                 keyPos %= keyLength;
  119.             }
  120.             else
  121.             {
  122.                 *resText++ = *text++;
  123.             }
  124.         }
  125.         *resText = '\0';
  126.     }
  127.     return result;
  128. }
  129.  
  130. int main()
  131. {
  132.     char str[] = { "ATTACKATDAWN" };
  133.     char key[] = { "LEMON" };
  134.     char* encoded = NULL;
  135.     char* decoded = NULL;
  136.  
  137.     printf("Test with separate functions for encode and decode\n");
  138.     printf("Original:\t%s\n", str);
  139.     encoded = vigenere_encrypt(key, str);
  140.     printf("Encoded:\t%s\n", encoded);
  141.     decoded = vigenere_decrypt(key, encoded);
  142.     printf("Decoded:\t%s\n", decoded);
  143.  
  144.     free(decoded);
  145.     free(encoded);
  146.  
  147.     printf("\nTest with one function both for encode and decode\n");
  148.     printf("Original:\t%s\n", str);
  149.     encoded = vigenere(key, str, 1);
  150.     printf("Encoded:\t%s\n", encoded);
  151.     decoded = vigenere(key, encoded, 0);
  152.     printf("Decoded:\t%s\n", decoded);
  153.  
  154.     free(decoded);
  155.     free(encoded);
  156.  
  157.     printf("\nTest for invalid key and message\n");
  158.     printf("Original:\t%s\n", NULL);
  159.     encoded = vigenere_encrypt(NULL, NULL);
  160.     printf("Encoded:\t%s\n", encoded);
  161.     decoded = vigenere_decrypt(NULL, NULL);
  162.     printf("Decoded:\t%s\n", decoded);
  163.  
  164.     free(decoded);
  165.     free(encoded);
  166.  
  167.     printf("\nTUKE test:\n");
  168.     printf("Original:\t%s\n", "Hello world!");
  169.     encoded = vigenere_encrypt("CoMPuTeR", "Hello world!");
  170.     printf("Encoded:\t%s\n", encoded);
  171.     decoded = vigenere_decrypt("CoMPuTeR", encoded);
  172.     printf("Decoded:\t%s\n", decoded);
  173.  
  174.     free(decoded);
  175.     free(encoded);
  176.  
  177.     printf("Test passed: %d\n", vigenere_encrypt("Ach poveda kdeze si mi tak dlho ako tazko za tebou cakam", "Bezali vsetci do mastale tu kravicka stala pekne na svojom mieste a vlci cusali v kute na pyskoch mali velke zamky") == NULL);
  178.     printf("Test passed: %d\n", vigenere_decrypt("Zase sa len po chvili ohlasi", "Kralova dcera zisla z koca a sadla na kona") == NULL);
  179.     printf("Test passed: %d\n", vigenere_encrypt(" !\"#$ % &'()*+", "sultanate") == NULL);
  180.     printf("Test passed: %d\n", vigenere_encrypt(" !\"#$ % &'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|", "canniness") == NULL);
  181.     printf("Test passed: %d\n", vigenere_decrypt(" !\"#$ % &'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|", "lamented") == NULL);
  182.  
  183.     return 0;
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement