Tuesday, June 14, 2022

Caesar Cipher and other stuff

Day 002: Caesar Cipher

How to implement Caesar cipher and other stuff.


There is an old programming exercise to implement a simple string transformation. Of course, for beginners, it's too hard to understand, so the programming task is dumbed down. The problem is, the usual solution are implemented using ASCII chart calculation. I don't know about you, but I think a simple character array implementation is much more suitable to beginners. 


And if you have been using Unix/Linux for a while, I'm sure you wonder just how difficult it is to implement some of the programs. Sure, the source code is out there, but how about a simple one for learning purposes? Therefore, I decided to just implement a simple cipher program. As a bonus, I decided to have a user configurable keys, so that the cipher isn't limited to A=3 as in traditional Caesar cipher.


The program will take 2 string parameters, called Set1 and Set2. This will determine the plain text, and the key. To use it as Caesar cipher, do it like this:


caesar abcdefghijklmnopqrstuvwxyz cdefghijklmnopqrstuvwxyzab


That's all there is to it. Speaking of which, there is another encoding technique that is quite standard, called ROT13. ROT13 is basically Caesar cipher shifted 13 places. You use it like this:


caesar abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm


As you can see, by having both the plain text and the key be provided to the program, you can easily change the cipher without too much fuss!


Another way to use this program is to use it either to lower case, or to upper case. Like so:


caesar ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz

caesar abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ


Pretty neat! You can even reverse the alphabet for some unique writings:


caesar abcdefghijklmnopqrstuvwxyz zyxwvutsrqponmlkjihgfedcba


And if you mix the alphabet just so, you may even come up with some alien sounding words:


caesar abcdefghijklmnopqrstuvwxyz alienssoundingoratoryz


If you notice, the last example has a shortened key. That is intentional. You don't have to provide a direct match just to have fun! "Hello Sailor!" becomes "Hniio Sauiot!", it's just enough weirdness without being to alien to recognize.


And if you have been following the capabilities so far, I suggest that you take it to the next step and study a standard program called "tr", which is what this is all about.


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

int tr(char Set1[],char Set2[]) {
  int i,j,c; char *p;
  j=strlen(Set2);
  while ((c=getchar())!=EOF) {
    i=(p=strchr(Set1,c))-Set1;
    i=(i<j)?i:j-1;
    if (p) putchar(Set2[i]);
    else   putchar(c);
  }
  return 0;
} 

int main (int argc, char *argv[] ) {
  if   (argc<3) puts("Usage: tr SET1 SET2\n");
  else tr(argv[1],argv[2]);
  return 0;
}


One last thing: You can use this to delete characters from the text. Suppose you want to eliminate vowels from the text. You can do it this way: 


caesar aeiou ''

caesar aeiou '_' <test.txt | sed "s/_ */_/g" | sed "s/_//g"


The quotes specify empty string, and this will delete the characters no problem. Quite an interesting capability. Couple it with some judicious regex, and you have a nice vowel remover, indeed!


No comments:

Post a Comment