#+title: Reviving Caesar with a Cherry-flavored Crystal
#+AUTHOR: Crystal & Sloth
#+OPTIONS: ^:{}
#+OPTIONS: num:nil
#+EXPORT_FILE_NAME: ../../../../blog/c/cherry.html
#+HTML_HEAD:
#+HTML_HEAD:
#+OPTIONS: html-style:nil
#+OPTIONS: toc:nil
#+HTML_HEAD:
#+HTML_LINK_HOME: https://crystal.tilde.institute/
* What ?...
That is probably your reaction reading this title, and no, this isn't a randomly generated sentence, but rather a simple encryption algorithm I recently made (Actually the first encryption algorithm i make at all!!). Meet *Cherry-Crystal Encryption*.
* Okay so, what is this all about ?
This encryption Algorithm that we will call *CCE* for short, takes inspiration from the Caesar cipher which needn't an introduction (you can find great explanations online). But what about mine you might ask ?
- It's actually pretty simple. We start with a *Cherry* or a *Visible phrase*, or a *Decoy*, that we will share to people who we don't want to know the secret phrase..
- Then we ask the user to enter their *Crystal*, *invisible phrase* or *secret*.
- The program then outputs an array of Integers called the *Mask*, or the *Shift*. That is, the shift required to go from cherry_{i} to crystal_{i}.
- Finally, we use both the *Cherry* and *Mask* to get the *Crystal*, a single missing number or letter from both of them can and will output rubbish content.
* The Code :
#+BEGIN_SRC c
#include
#include
#include
void sloth(char cherry[], char crystal[], int mask[]) {
int i;
for (i = 0; i < strlen(cherry) - 1; i++) {
mask[i] = cherry[i] - crystal[i];
}
for (i = strlen(cherry) - 1; i < strlen(crystal) - 1; i++) {
mask[i] = crystal[i];
}
}
void moon(char cherry[], char crystal[], int mask[], int length) {
int i, end = 1;
for (i = 0; i < length; i++) {
if (i == strlen(cherry) - 1 || end == 0) {
crystal[i] = mask[i];
end = 0;
} else {
crystal[i] = cherry[i] - mask[i];
}
}
}
int main(int argc, char *argv[]) {
const int size = 1028;
char cherry[size], cherry2[size], crystal[size], crystal2[size];
int mask[size], mask2[size], i;
int length = 0;
puts("Enter the Cherry: ");
fgets(cherry, size, stdin);
puts("Enter the Crystal: ");
fgets(crystal, size, stdin);
sloth(cherry, crystal, mask);
for (i = 0; i < strlen(crystal) - 1; i++) {
printf("%d ", mask[i]);
length++;
}
printf("\nYour mask is : %d characters long", length);
puts("\n===Decryption: ===\n");
puts("Enter the Cherry: ");
fgets(cherry2, size, stdin);
puts("Enter the size of the Mask: ");
scanf("%d", &length);
puts("Enter the mask: ");
for (i = 0; i < length; i++) {
scanf("%d", &mask2[i]);
}
puts("The Crystal is: ");
moon(cherry2, crystal2, mask2, length);
puts(crystal2);
return 0;
}
#+END_SRC
The program has been tested both on Alpine OS with Musl libc (thanks [[https://kaa.neocities.org/][Kin]]) and on OpenBSD 7.5-current. In the close future I will make a git repo as i'm planning to upgrade it and just make it better overall, who knows, maybe i will make a library out of it!!
* How does it work ?
** Slothing (Encrypting) 🦥:
+What is it with these names I pick ?+ Anyways, the *sloth(char *cherry, char *crystal, int *mask)* void function takes as parameters three variables:
- A pointer to a *char array* or simply said *a string*, It's the *Cherry*.
- Another pointer to the *Crystal*.
- And Finally, a pointer to an array of integers *The Mask* which will be output-ed by the function.
The general idea of it is like this : (we will use a quick example)
- *Cherry*: H e l l o \0.
- *Crystal*: W o r l d \0.
- Cherry[0] here is *H*, or in ASCII *72*. And Crystal[0] is *W* or *87*.
- Mask[0] in this case is : Cherry[0] - Crystal[0]. which is *-15*. We then repeat the same steps for each letter on the *Crystal*.
Why the emphasis on *Crystal* ? Because we might end up with a case of a Crystal larger than a Cherry. we set the offset to the ASCII value of *Crystal[i]*, okay which to be fair is not the safest option out there, but I'm planning on fixing it sooner or later. In the case of a large Cherry but a small Crystal...it works but now looking at the code, i have no idea why it works the intended way....
** Mooning (Decrypting) 🌕:
The function *moon(char *cherry, char *crystal, int *mask, int length)* works the same way as the sloth function, but in reverse and a small change.
- *The for loop goes through all the elements of the Mask and reconstructing the Crystal using the reverse equation of the encryption*. But when it arrives at the end of the *Cherry* (here we enter the case of a Cherry smaller than a Crystal). Then we will just assume that *Mask[i]* is the ASCII code of *Crystal[i]*, and we continue this assumption until the end of the loop.
And voila that's it. Of course there might be some things I will change, but the overall concept is here!