Encryption is a technique that transforms original data to make it unintelligible.
However, it's useless if you don't understand it, so it must be reversible. Restoring the data to its original state is called decryption, and the original data itself is called plaintext.
The purpose of encryption is, of course, to prevent unauthorized third parties from stealing data.
Therefore, unlike other algorithms, cryptographic strength is prioritized above all else.
No matter how fast, an algorithm that's easily deciphered has limited utility.
Caesar cipher
It is said that the famous Julius Caesar was the first to use cryptography in the world.
The method is extremely simple; it only involves shifting the letters a few characters at a time.
For example, if you shift each letter of CAESAR, it becomes DBFTBS.
If you shift each letter back one position in reverse order, you can derive the original CAESAR.
The following program applies to a generic binary file.
Source code
/* 使用法
CodeCaesar(入力File名、出力File名、パスワード);
パスワードは0~255の範囲内のnumericsにします
パスワードをマイナスの数にすれば復号できます。
*/
void CodeCaesar(char finame[], char foname[], int key)
{
FILE *fi, &*fo;
int value;
fi = fopen(finame, "rb");
if (fi == NULL) return;
fo = fopen(foname, "wb");
if (fo == NULL) return;
while ((value = getc(fi)) != EOF) {
putc(value + key, fo);
}
fclose(fi);
fclose(fo);
}
This cipher can be easily deciphered by comparing it to the original data.
Exclusive OR and Cryptography
The Caesar cipher is simple, so it can be easily deciphered.
So, to make it a bit more confusing, we'll use exclusive OR.
キーワード
【Exclusive OR】
In binary calculations, the output is 0 when the same number is input.
"The exclusive OR (XOR) operation is suitable for encryption because it can produce seemingly random values."
To calculate the exclusive OR in C, use the ^ operator.
The following program applies to a generic binary file.
Source code
/* 使用法
CodeExor(入力File名、出力File名、パスワード);
※パスワードは0~255の範囲内のnumericsにします。
※同じパスワードで復号できます。
*/
void CodeExor(char finame[], char foname[], int key)
{
FILE *fi, &*fo;
int value;
fi = fopen(finame, "rb");
if (fi == NULL) return;
fo = fopen(foname, "wb");
if (fo == NULL) return;
while ((value = getc(fi)) != EOF) {
putc(value ^ key, fo);
}
fclose(fi);
fclose(fo);
}
This code appears unbreakable at first glance.
If you test 256 passwords, it will be cracked.(For a computer, it would be instantaneous.)
Long password
"Previous encryption methods have been easily compromised because they only allowed for 256 possible passwords."
So, we're enabling longer passwords.
The thinking is simple.It's just a matter of repeating multiple numbers.
The following program applies to a generic binary file.
Source code
/*
使用法
CodeExor(入力File名、出力File名、パスワード文字列);
パスワードは任意の長さの文字列を指定できます。
同じパスワードで復号できます。
*/
void CodeExorLong(char finame[], char foname[], char key[])
{
FILE *fi, *fo;
int value, i = 0;
fi = fopen(finame, "rb");
if (fi == NULL) return;
fo = fopen(foname, "wb");
if (fo == NULL) return;
while ((value = getc(fi)) != EOF) {
putc(value ^ key[i], fo);
i++;
if (key[i] == '\0') i = 0;
}
fclose(fi);
fclose(fo);
}
This allows us to increase the number of possible passwords beyond 256.
Considering the performance of current computers, passwords of just a few characters can be cracked very quickly.
Applications of Pseudorandom Numbers
The result of exclusive OR may seem nonsensical at first glance, but it actually has a clear pattern.
To prevent this, we make the pattern less obvious by using pseudo-random numbers.
In pseudo-random number generation, the same initial value will always produce the same sequence of numbers.
If you set the initial value based on the password, you will always get the same calculation result.
Random number algorithms
If the compiler differs, the standard library's random number algorithm will also differ. Therefore, the calculation results may differ depending on the compiler. To prevent this, you'll also need to create your own random number algorithm.
There are various ways to generate an initial value from a password, but for this time, we will simply use the sum of the character codes.
The following program applies to a generic binary file.
Source code
/*
CodeExorRandom(入力File名、出力File名、パスワード文字列);
パスワードは任意の長さの文字列を指定できます。
同じパスワードで復号できます。
*/
int GetRandom(int min, int max)
{
return min + (int)(rand() * (max - min + 1.0) / (1.0 + RAND_MAX));
}
void CodeExorRandom(char finame[], char foname[], char key[])
{
FILE *fi, *fo;
int value, early = 0, i;
fi = fopen(finame, "rb");
if (fi == NULL) return;
fo = fopen(foname, "wb");
if (fo == NULL) return;
for (i = 0; key[i] != '\0'; i++) {
early += key[i];
}
srand(early);
i = 0;
while ((value = getc(fi)) != EOF) {
putc(value ^ GetRandom(0, 255), fo);
i++;
if (key[i] == '\0') i = 0;
}
fclose(fi);
fclose(fo);
}
"Deciphering this requires analyzing the method for generating random numbers, which is beyond the ability of an amateur."
However, someone with sufficient knowledge and the will to do so could decipher it.
The practicality of this encryption.
All the encryptions shown here are simple and can be deciphered if one is inclined to do so. However, it's fast and easy to program. It's perfectly practical to incorporate it into save data for a homemade game.
By the way, save data in commercially available games can sometimes be easily modified. とくに、美少女系gameはシステムセーブデータを 0xFF で埋めるだけで、 CGや回想が見られるようになることもありますね。
About This Site
Learning C language through suffering (Kushi C) is
This is the definitive introduction to the C language.
It systematically explains the basic functions of the C language.
The quality is equal to or higher than commercially available books.