Reputation: 49
I am working on a problem and I am a bit stuck so I thought to ask for your help. I want to make a program with the following capabilities. The user will give a 4 digit cipher key and a text.
Then the text will be converted in cipher using the following method. Let's say that the text input was 'ABC' and the key was 123. Then, using the ASCII table the 'ABC' will be converted to 'BDF'. The text will be moved K positions forward in the ASCII table, where K is the corresponding digit of the key. Consider the text infinite. My first action was to convert the key to an array.
//scanning the cypher key
scanf("%d", &cypherkey);
//converting the cypher key into an array using a practical mathematic method for extracting its digit
int keyarray[4];
keyarray[0]= cypherkey/1000;
keyarray[1]= (cypherkey-keyarray[0]*1000)/100;
keyarray[2]= ((cypherkey-keyarray[0]*1000)- keyarray[1]*100)/10;
keyarray[3]= ((cypherkey-keyarray[0]*1000)- keyarray[1]*100)-keyarray[2]*10;
So, now I have the key in an array. However, I can't find a good way to read the text and then cipher it. I can't use an array because we don't know the length of the text.
I would appreciate any help!
Upvotes: 2
Views: 3524
Reputation: 4089
I believe there's a simpler way to do this. The algorithm you're describing is known as a generalized Caesar cipher. The congruence relation that ciphers text is C = rP + s (mod 26) where P is the plain text, r is a multiplier and s is the shift. In the situation you describe, you have a multiplier of 2 and a shift of 1. If you want to avoid using a table, you can just get the unicode for each letter in your plain text and subtract a consistent offset from the unicode so that you always end up with a number under 26. To decipher ciphertext, you need to multiply the ciphertext by the modular inverse of r add the offset you applied and then convert back to a character from the numeric unicode representation.
In short, you need to get the unicode for a character, subtract some offset, multiply by 2, add 2 and take the mod of that number mod 26 to encipher something.
To reverse the process, multiply the ciphertext, minus 1, by the modular inverse, add the offset and convert back to a character.
Upvotes: 0
Reputation: 93468
I took a shot and the input text is hardcoded within the application. The example below is not production code, its only meant for educational purposes.
On my approach there are 2 challenges:
Writing the function that counts how many digits there are in a number:
Implementing the function that retrieves a specific digit of a number;
.
#include <stdio.h>
#include <string.h>
int count_digits(int number) // // http://stackoverflow.com/questions/1489830/efficient-way-to-determine-number-of-digits-in-an-integer
{
int digits = 0;
if (number < 0)
digits = 1;
while (number)
{
number /= 10;
digits++;
}
return digits;
}
char get_digit(int number, int index) // starts at index 0
{
if (number == 0)
return (char)0;
int n_digits = count_digits(number);
if (index > n_digits)
return (char)-1;
char digit = -1;
int i;
for (i = 0; i < (n_digits-index); i++)
{
digit = number % 10;
number /= 10;
}
return digit;
}
int main()
{
printf("* Type the encoding key (numbers only): ");
int key = 0;
scanf("%d", &key);
int key_digits = count_digits(key);
//printf("* The key has %d digits.\n", key_digits);
char input_msg[] = "ABCABC"; // This is the input text
int input_sz = strlen(input_msg);
//printf("* Input message [%s] has %d characters.\n", input_msg, input_sz);
int i, d = 0;
for (i = 0; i < input_sz; i++)
{
if (d >= key_digits)
d = 0;
input_msg[i] += get_digit(key, d);
d++;
}
printf("* Encoded text is: %s\n", input_msg);
return 0;
}
Outputs the following...
For input text ABC
:
$ ./cypher
* Type the encoding key (numbers only): 123
* Encoded text is: BDF
$ ./cypher
* Type the encoding key (numbers only): 234
* Encoded text is: CEG
For input text ABCABC
:
$ ./cypher
* Type the encoding key (numbers only): 123
* Encoded text is: BDFBDF
Upvotes: 1
Reputation: 2192
The most straightforward answer, ignoring all performance concerns, is to just handle one character at a time.
basically,
Real-world implementations would probably read input into a buffer, operate on the entire buffer, and repeat, for performance reasons.
Upvotes: 1