How to multiply and print the digits of 2 numbers recursively - c

I'm looking for a way to multiply the digits of two numbers (not necessarily of the same digits length) recursively without using loops in the following way:
let's say the numbers are 123 and 567. I'm trying to figure out a way to print:
5
6
7
10
12
14
15
18
21
it's the left most digit of the first number times every digit of the second number starting from the left and moving in both the right most.
the function must fit the prototype:
void multi(int a, int b);
I've managed to dive recursively to 1 and 5 from there to 1 56 and then 1 567 and in every call I print the result of a%10 * b%10.
but when backtracking to 12 567 the function dives to 1 567 again.
here's my best attempt:
int main()
{
int a, b;
scanf("%d %d", &a, &b);
multi(a, b);
return 0;
}
void multi(int a, int b)
{
if (a == 0)
return;
multi(a / 10, b);
if(b /10 != 0)
multi(a, b / 10);
printf("%d\n", a % 10 * b % 10);
}
list of restricions:
no loops
single function
mandatory prototype

This is a possible solution:
void multi(int a, int b)
{
// First "consume" the first parameter
if ( a > 9)
multi(a / 10, b);
// Then the second, passing only one digit of the first
if ( b > 9 )
multi(a % 10, b / 10);
// Multiply the last digits before backtracking
printf("%d\n", (a % 10) * (b % 10));
}
Testable HERE.

Here the catch is that you need to run a routine for each sub a value of a with all of sub b values.
I think you need a bit more of divide a concur approach here. you send your reduced values but you fail to treat all the cases properly.
I would suggest a simpler approach which takes the values a and b, then for each a sub value run a routine to show all of the different cases by passing the entire b each time.
so that for each sub a value you get all of the multiplications with the sub b values.
#include <stdio.h>
static void AuxMul(int a, int b)
{
int bs;
if(0 == b)
{
return;
}
bs = b%10; /*save res for multipication */
AuxMul(a, (b/10)); /*now sent it back with the same a value and reduced b value */
printf("|%d| \n", (a*bs));
}
void MultPrintRec( int a, int b)
{
int as = 0;
if (0 == a )
{
return;
}
as = a%10; /*get the value to mult. with all the b values */
MultPrintRec(a/10, b); /*do this until there is nothing to send */
AuxMul(as, b); /*send to a rec aux function that will take care of sub a value sent with all of the sub b values*/
}
int main() {
MultPrintRec(123, 567);
return 0;
}
Hope this is clear and helpful, Good luck

Related

What is the magic behind that recursive function?

Question:
Can you explain me how that fuction returns the correct result 16?
I am new to programming and now this code is recursive, however I think I am getting lost as much as I think I understand them. Even though, I believe I figure out factorial recursions or fibonacci ones.
The base is 0, that's good, but I can't figure out why I get 16... I printed every variable inside the function and dubugged, but those did not help more than troubling. When b variable is 0 (and a variable is 32) the condition is met, but why it returns value 16? I would understand a kind of function as n * fact(n-1) as in a classic factorial fuction example, but here I can't visualize how the recursion returns the expected result.
Code:
#include <stdio.h>
int fun(int a, int b)
{
if (b == 0)
{
return 0;
}
if (b % 2 == 0)
{
return fun(a+a, b/2);
}
return fun(a+a, b/2)+a;
}
int main()
{
printf("%d\n", fun(4, 4));
return 0;
}
Thanks in advance!
Add printouts and it will become very clear:
int fun(int a, int b)
{
printf("fun(%d, %d)\n", a, b);
if (b == 0) {
printf("b == 0, returning 0\n");
return 0;
}
if (b % 2 == 0) {
printf("b is even, returning f(%d, %d)\n", a+a, b/2);
return fun(a+a, b/2);
}
printf("b is odd, returning f(%d, %d) + %d\n", a+a, b/2, a);
return fun(a+a, b/2)+a;
}
Output:
$ ./a.out
fun(4, 4)
b is even, returning f(8, 2)
fun(8, 2)
b is even, returning f(16, 1)
fun(16, 1)
b is odd, returning f(32, 0) + 16
fun(32, 0)
b == 0, returning 0
16
So what happens in the end is that f(16, 1) will return f(32, 0) + 16 and f(32, 0) evaluates to zero, so 16 is returned.
You could also do like this, but do note that this will alter the order of the outputs because the printout need to wait for the return:
int fun(int a, int b)
{
printf("fun(%d, %d)\n", a, b);
if (b == 0) {
printf("b == 0, returning 0\n");
return 0;
}
if (b % 2 == 0) {
int ret = fun(a+a, b/2);
printf("b is even, returning f(%d, %d) = %d \n", a+a, b/2, ret);
return ret; //fun(a+a, b/2);
}
int ret = fun(a+a, b/2) + a;
printf("b is odd, returning f(%d, %d) + %d = %d \n", a+a, b/2, a, ret);
return ret;
}
Output:
$ ./a.out
fun(4, 4)
fun(8, 2)
fun(16, 1)
fun(32, 0)
b == 0, returning 0
b is odd, returning f(32, 0) + 16 = 16
b is even, returning f(16, 1) = 16
b is even, returning f(8, 2) = 16
16
A good way to understand recursion is to use pen and paper to see why the order of printouts is so different in these cases. But I leave that to you.
I find helpful to think about these kind of recursive functions as mathematical tools. What I mean is that a recursive function works if:
It always says the truth.
You can prove that it ends, eventually.
You don't say, but I guess that your function fun(a, b) does a multiplication a * b. And it does it by reducing it:
If b==0 then a * b -> 0
Else, if b is even then a * b -> (a+a) * (b/2).
Else (b is odd), a * b -> ((a+a) * (b/2)) + a
These equations are trivially true, as long as b >= 0 of course, which I assume that is a precondition of your function.
You also can see that it will eventually finish, as the value of b gets smaller and smaller, and it will always reach 0 at the end.
That should be enough to believe that your function works. If you want to trace each intermediate step, you can check your truth every time to ensure that you doing it properly.
a=4, b=4, b is even, so foo(4,4) -> foo(8, 2) (we know that 4*4 == 16, and 8*2 == 16 too, so we are on the right track).
a=8, b=2, b is even, so foo(8, 2) -> foo(16, 1) (16 * 1 ==16, we are still ok).
a=16, b=1, b is odd, so foo(16, 1) -> foo(32, 0) + 16. Here is the tricky part, this call is not tail-recursive, there is the latter addition. But still, 32*0 + 16 = 16 so we are on the right track.
a=32, b=0 b is 0 so it returns 0 (ok, because 32*0 = 0).
Then there is the latter sum: 0 + 16 = 16 and that value is returned all up to main.
There are two things about recursive functions:
recursive functions are not special. Eg. they work the same way as if you called a different function that served the same purpose for the smaller sub problems.
All functions will have their own arguments and local variables. The location of a and b is new for each invocation of a fucntion. Thus if you call the same function from itself there will be no interference between the two!
You should do substitution rules:
Replace the call with the code that is executed according to the conditionals.
Repeat until you no longer have anything to call
Example:
fun(4, 4) // initial call
fun(4+4, 4/2) // because 4 % 2 == 0
fun(8+8, 2/2) // because 2 % 2 == 0
fun(16+16, 1/2) + 16 // because 1 % 2 != 0.
0 + 16 // because 1/2 == 0 and then b == 0
16 // because 0 + 16 == 16

Print a different result than actual answer (Ciel and A-B Problem)

Input:
An input contains 2 integers A and B.
Output:
Print a wrong answer of A-B. Your answer must be a positive integer containing the same number of digits as the correct answer, and exactly one digit must differ from the correct answer. Leading zeros are not allowed. If there are multiple answers satisfying the above conditions, anyone will do.
Code:
#include <stdio.h>
int no_of_zeroes(int x);
int main()
{
int a, b;
int res1, res2;
int n1, n2;
scanf("%d",&a);
scanf("%d",&b);
res1 = a - b;
res2 = res1 + 10;
n1 = no_of_zeroes(res1);
n2 = no_of_zeroes(res2);
if(res1 < 9) printf("%d",res1 + 1);
else if(res1 == 9) printf("%d",res1-1);
else if((n1 == n2) && (res1 > 9)) printf("%d",res2);
else if((n2 > n1) && (res1>9))
{
res2 = res2 - 20;
printf("%d",res2);
}
}
int no_of_zeroes(int x)
{
int count = 0;
while(x>0)
{
x = x / 10;
count++;
}
return count;
}
Error:
What different should i do, basically else if blocks are creating trouble.
Your answer must be a positive integer containing the same number of digits as the correct answer
So the answer should be a-b. But the statement also says
exactly one digit must differ from the correct answer
Since it didn't specify the position of the digit, changing the last digit only should give us the correct answer to this problem. And so counting the number of digits of the difference is redundant.
Now the issue is - how to change the last digit? It's simple. We add 1 to the difference.
But there is a catch! If the difference is 99 and we add 1 to it, the result will be 100. Here, not only we're changing more than one digit, but also the number of digits.
And so, all we have to do is subtract 1 from the difference if the last digit of the difference is 9.
And so, the if-else block should look something like this:
int diff = a - b;
if(diff%10 == 9) {
diff--;
}
else {
diff++;
}
Here's my full code:
#include <stdio.h>
int main(void) {
int a, b;
scanf("%d%d", &a, &b);
int diff = a - b;
if(diff%10 == 9) {
diff--;
}
else {
diff++;
}
printf("%d\n", diff);
return 0;
}
On a different note, the function no_of_zeroes(int x) will return 0 if x=0. But, it should return 1 under general circumstances. And so the function should be something like this:
int no_of_digits(int x)
{
/* Adding the following line should fix the issue */
if(x==0) return 1;
int count = 0;
while(x>0)
{
x = x / 10;
count++;
}
return count;
}
I think you are making this much more complicated than needed. All you need is to check the last digit of the correct result and then change it.
For 0 and positive numbers:
last digit is 0 : add 1
last digit is 1 : add 1
...
last digit is 8 : add 1
last digit is 9 : subtract 1
For negative numbers, you simply change the sign and handle it as the positive number. This can be done because -123 has the same digits as 123.
So the code can be:
void wrongCalc(int a, int b)
{
int res = a - b; // Calculate result
if (res < 0) res = -res; // Change sign if negative
int lastDigit = res % 10; // Find last digit
if (lastDigit == 9)
{
--res; // Subtract 1
}
else
{
++res; // Add 1
}
printf("%d - %d = %d (correct result is %d)\n", a, b, res, a-b);
}
Limitations:
1) The program doesn't handle the possible integer overflow in a-b
2) The program doesn't handle the possible integer overflow in res = -res;
3) The program doesn't handle the case where the correct result is INT_MAX

Code not assessing peaks correctly

i have a code that prints out the number of peaks and their given magnitudes. the input is in the form of a single line that contains random integers separated by white space. a peak is only defined to be so when it is directly preceded and followed by a smaller value.
examples:
0 4 18 18 26 40 40 29 25 2 0 //has one peak of magnitude 40.
20 10 20 /*has no peaks, because both 20's are either not
preceded or followed by a smaller number.*/
the code fails to behave correctly when the input data, c, begins with a declining set of numbers.
for example, the input: 9 8 7 6 5 4 returns a peak of "9", when it shouldn't return any magnitude.
another situation where it's behaving incorrectly is when we have the following input: 10 10 10 5 5 5 12 12 12 -1. its returning a magnitude of "10", while again, it shouldn't return any magnitude because it doesn't fulfill the conditions of a peak .
the following is the code:
#include <stdio.h>
int main(void)
{
int a = 0;
int b = 0;
int c = 0;
int counter = 0;
scanf("%d", &c);
printf("Number Magnitude\n");
while (c >= 0){
if ((b > a) && (b > c)) { //to check if we have a peak
counter++;
printf("%4d%11d\n", counter, b);
a = b;
b = c;
scanf("%d", &c);
}
else if ((a < b) && (b == c)) {
b = c;
scanf("%d", &c);
}
else {
a = b;
b = c;
scanf("%d", &c);
}
}
}
i prefer to keep the level of coding as minimum as possible, as i haven't done more than loops and if statements at this stage.
The issue is being caused because you initialize your boundary values to the minimum possible value. Any possible peak value will test positive when compared to that boundary value.
A small change fixes it, both boundary values should be set to a value that tests negative when compared to any possible peak value:
int a = INT_MAX;
int b = INT_MAX;
You will however to detect new lines and reset your values if you want to be able to do multiple lines of input, but I believe this is an existing problem
In that case, you should try to ask the program to mimic what you would to by hand: you must considere 3 value, so you must read 3 values before testing for a peak. And you should always control the return value from scanf to be able to process and end of file or an incorrect input.
Your code could become:
#include <stdio.h>
int main(void)
{
int a = 0;
int b = 0;
int c = 0;
int counter = 0;
int cr;
cr = scanf("%d%d%d", &a,&b,&c);
if (cr != 3) {
printf("Incorrect input\n");
return 1;
}
printf("Number Magnitude\n");
while ((cr > 0) && (c >= 0)) {
if ((b > a) && (b > c)) { //to check if we have a peak
counter++;
printf("%4d%11d\n", counter, b);
a = b;
b = c;
}
else if ((a >= b) || (b != c)) {
a = b;
b = c;
} // nothing to do if a<b and b==c
cr = scanf("%d", &c); // read once outside of the loop
}
return 0;
}
BTW, above code allows multi-line input.

3-digit integer number program won't execute

Yes, this is a basic C coding homework problem. No, I am not just looking for someone to do it for me. Considering that this is my first programming class, I'm not surprised that I can't get it to work, and I'm certain there is plenty wrong with it. I just want some help pointing out the problems in my code and the things that are missing so that I can fix them on my own.
Homework Question:
Write a program to read ONLY one integer number (your input must be
one 3 digit number from 100 to 999), and to think of a number as
being ABC (where A, B, and C are the 3 digits of a number). Now,
form the number to become ABC, BCA, and CAB, then find out the
remainder of these three numbers when they are divided by 11.
Assume remainders would respectively be X, Y, and Z and add them
up as X+Y, Y+Z, and Z+X. Now if any of these summations is odd
number, increase it by 11 if the summation plus 11 is less than 20,
otherwise decrease the summation by 11 (this summation operation
must be positive number but less than 20). Finally, divide each
of the sums in half. Now, print out all the resulting digits.
My Code:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
//Declare all variables
int OrigNumber;
int x, y, z;
int number;
number = x, y, z;
int sum;
//
printf("Input a three digit number");
//
int c;
c = OrigNumber %10;
//
int b;
b=((OrigNumber - c) % 100)/10;
//
int a;
a = (OrigNumber - (b + c))/100;
//
int abc, bca, cab;
abc = (a*100) + (10*b) + c;
bca = (10*b) + c + (a*100);
cab = c + (a*100) + (10*b);
//
if((number % 2) == 1)
{
if(number + 11 < 20)
number += 11;
else if((100 - 11 > 0) && (100 - 11 < 20))
number -= 11;
}
//
x = abc/11;
y = bca/11;
z = cab/11;
//
sum = (x + y),
(y + z),
(z + x);
}
To start with, you need to read the input. Start with a prompt that includes a carriage return:
printf("Input a three digit number: \n");
Since it's a three digit number, you could add the following line to read the input:
scanf("%3d", &OrigNumber);
The next bit of code works quite well until you get to your if (number % 2) which is meaningless since you didn't really define number - well, you did, but the line
number = x, y, z;
does NOT do what you think it does. If you add
printf("So far I have abc=%d, bca=%d, cab=%d\n", abc, bca, cab);
after you first read in the number and computed those three, you will see you are well on your way.
Note that
number = x, y, z;
Uses a thing called the "comma operator". All the things (a,b,c) are "evaluated" but their values are not returned. At any rate, where you have that line, you didn't yet assign a value to x,y and z.
Is that enough to get your started?
update now that you have had a few hours to mull this over, here are a few more pointers.
Your computation of abc, cab, bca makes no sense. I will show you just one of them:
cab = c*100 + a*10 + b;
Next you need to compute each of x, y and z. Again, here is one of the three:
y = bca%11;
Now you have to make the sums - I call them xy, yz, and zx. Just one of them:
zx = z + x;
Next, to deal with the instruction: "Now if any of these summations is odd number, increase it by 11 if the summation plus 11 is less than 20, otherwise decrease the summation by 11:
if(xy % 2 == 1) {
if(xy + 11 < 20) xy += 11; else xy -= 11;
}
use similar code for all three sums. Then "divide by 2":
xy /= 2;
repeat as needed.
Finally, print out the result:
printf("xy: %d, yz: %d, zx: %d\n", xy, yz, zx);
The amazing thing is that if you did this right, you get the original numbers back...
You could make the code more compact by using an array of values and looping through it - rather than repeating the code snippets I wrote above with different variables. But I suspect that is well outside the scope of what you are expected to know at this point.
Can you take it from here?
#include <stdio.h>
int main()
{
//Declare all variables
int OrigNumber;
int a, b, c;
int abc, bca, cab;
int x, y, z;
int xplusy , yplusz, xplusz;
printf(" A program to read ONLY one integer number.\n Input must be one 3 digit number from 100 to 999 : ");
scanf("%d", &OrigNumber); // Get input from console
if(OrigNumber > 999 || OrigNumber < 100) {
printf("Invalid number. Quiting program. This is error handling. Important while learning programming.");
return 0;
}
c = OrigNumber %10; // digit at unit's place
b=((OrigNumber) % 100)/10; //digit at the ten's place
a = (OrigNumber)/100; //digit at the 100's place. Note: 734/100 = 7. NOT 7.34.
printf("\n Three numbers say A,B, C : %d, %d , %d ", a, b, c);
abc = a*100 + 10*b + c;
bca = 100*b + 10*c + a;
cab = c*100 + a*10 + b;
printf("\n Three numbers say ABC, BCA, CAB : %d, %d , %d ", abc, bca, cab);
x = abc % 11; // Reminder when divided by 11.
y = bca % 11;
z = cab % 11;
printf("\n Three numbers say X, Y, Z : %d, %d , %d ", x, y, z);
xplusy = x + y; // Adding reminders two at a time.
yplusz = y + z;
xplusz = x + z;
printf("\n Three numbers X+Y, Y+Z, X+Z : %d, %d , %d ", xplusy, yplusz, xplusz);
if((xplusy % 2) == 1) {
if(xplusy + 11 < 20)
xplusy += 11;
else
xplusy -= 11;
}
if((yplusz % 2) == 1) {
if(yplusz + 11 < 20)
yplusz += 11;
else
yplusz -= 11;
}
if((xplusz % 2) == 1) {
if(xplusz + 11 < 20)
xplusz += 11;
else
xplusz -= 11;
}
xplusy /= 2; // Finally, divide each of the sum in half.
yplusz /= 2;
xplusz /= 2;
printf("\n Now print out all the resulting digits : %d, %d , %d \n", xplusy, yplusz, xplusz);
return 0;
}
int abc, bca, cab;
abc = (a*100) + (10*b) + c;
bca = (10*b) + c + (a*100);
cab = c + (a*100) + (10*b);
I suggest printing out the numbers at this point in the code.
printf( "%d %d %d", abc, bca, cab );
I think you'll see one of the problems you need to solve.
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
int n, a, b, c, abc, bca, cab, x, y, z, p, q, r;
scanf("%d", &n);
c=n%10;
b=(n/10)%10;
a=n/100;
abc=a*100+b*10+c;
bca=b*100+c*10+a;
cab=c*100+a*10+b;
x=abc%11;
y=bca%11;
z=cab%11;
p=x+y;
q=y+z;
r=z+x;
return 0;
}
Now if any of these summations is odd number, increase it by 11 if the
summation plus 11 is less than 20, otherwise decrease the summation by
11 (this summation operation must be positive number but less than
20). Finally, divide each of the sums in half. Now, print out all the
resulting digits.
i didnt get the final part, can you explain it more clearly?

encryption : RSA algorithm

I am implementing the RSA algorithm for encryption and decryption as given here:
http://www.di-mgt.com.au/rsa_alg.html
But could not understand the random prime number generation part in key generation.
So I am taking two prime numbers as inputs from user. I had difficulties with generating the e also. so I made it constant (e= 17)
Some prime number inputs working properly ( i.e encoding and decoding properly) in gcc under linux but not in devcpp under windows. (e.g 53,61)
Here is the key generation code:
/* Generates private and public keys and saves into two separate files */
void keygen()
{
int p,q,phi,d,e,n,s;
printf("\n Enter two prime numbers: ");
scanf("%d%d",&p,&q);
n = p*q;
phi=(p-1)*(q-1);
e=17;
// selec d such that d*e = 1+ k*phi for some integer k.
d = 0;
do
{
d++;
s = (d*e)%phi;
}while(s!=1);
printf("\n public key: { e=%d n=%d }",e,n);
printf("\n private key: { d=%d n=%d }\n",d,n);
}
Need help and suggestions in the prime number and e generation.
so you already know that e * d needs to be congruent to 1 mod phi(n)
since you know phi(n) a tuple (e,d) can be calculated by using the extended euclidean algorithm (EEA):
choose an integer for e (usually a small integer; this will be the public exponent, encryption will be faster with smaller exponents) that is less than phi(n) and greater than 2 (?... i think)
when you have a candidate for e, calculate the greatest common divisor (gcd) of e and phi(n) ... should be 1 ... if not, choose a new candidate for e and repeat (since there would be no modular inverse, in other words no private exponent d exists for this e and phi(n))
after you know that gcd(e,phi(n))==1 you can calculate d using the EEA (or as a shortcut, calculate EEA directly since it will also provide the GCD ... if that's not 1, choose a new value for e)
EEA (quick and dirty for calculating modular inverse):
imagine a table with 3 columns:
lets say those columns are named: b, q and t
so the lines of that table will look like:
b0, q0, t0
b1, q1, t1
...
(and so on)
the first 2 rows will be initially filled.
for all other rows there is an itterative rule that can be applied to the previous two rows that will result in the values for the next row
the first 2 rows are:
phi(n), NO_VALUE, 0
e, floor(phi(n)/e), 1
the itterative rule to create the next row is: (where [] is an index operator for selecting the row)
b[i] = b[i-2] mod b[i-1]
q[i] = b[i-1] / b[i] (integer division, no fractions ... )
t[i] = t[i-2] - ( q[i-1] * t[i-1] )
you can abort the scheme when b[i] becomes 0 or 1 ... you don't really need q for the last row ...
so if b[i] is 0, b[i-1] can not be 1 since you should have aborted when you calculated b[i-1] if that were 1 ...
if you reach b[i]==0, b[i-1] is your gcd ... since it is not 1 you need a new value for e
if b[i]==1 your gcd is 1, and there is an inverse ... and that is t[i] (if t is negative, add phi(n))
example with real values:
let's say phi(n) is 120
let's say we choose 23 as a candidate for e
our table will look like:
b q t
120 – 0
23 5 1
5 4 -5
3 1 21
2 1 -26
1 2 47
the last calculated b is 1 so => gcd(23,120) == 1 (proof: the inverse exists)
the last calculated t is 47 => 23*47 mod 120 == 1 (t is the inverse)
I don't have the answer, but if the same code compiled with two different compilers gives different answers I would guess that some of the types are of different size or you are implicitly relying on undefined behaviour somewhere.
The first thing you should do is, given the same prime number pairs, check that all the constants you generate come out the same in both implementations. If not, your key pair generation algorithms are at fault.
The next thing is to make sure that your input data for encryption is absolutely identical on both systems. Pay particular attention to how you deal with end of line characters. Bear in mind that, on Windows, end of line is \r\n and on Linux it is \n. Most Windows library implementations will convert \r\n to \n as the file is read in if "r" is supplied as the mode parameter to fopen(). Your implementation might be different.
Finally, whatever the problem is, on no account ever use gets() If you even catch yourself thinking about using it again, you should remove the frontal lobes of your brain with an ice pick.
Following the practical notes at the end of the linked page you would arrive at something like this for the prime generation:
unsigned int get_prime(int e)
{
while (true)
{
unsigned int suspect = 1 + (unsigned int)(65535.0 * rand() / (RAND_MAX + 1.0));
suspect &= 0x0000FFFF; // make sure only the lower 16bit are set
suspect |= 0xC001; // set the two highest and the lowest bit
while (!test_prime(suspect))
{
suspect += 2;
}
if (suspect < 65536 && gcd(e, suspect - 1) == 1)
return suspect;
}
}
test_prime is supposed to be an implementation of the Miller-Rabin test. The function above makes certain assumptions and has some drawbacks:
int is 32 bit
RAND_MAX is larger than 65536
rand() is usually not a good random number generator to use for serious encryption
The generated primes are 16bit so obviously not large enough for serious encryption anyway
Don't use this in any production code.
According to the article it seems ok to choose e fixed.
Dear Friend just follow this algorithm
Key generation
1) Pick two large prime numbers p and q, p != q;
2) Calculate n = p × q;
3) Calculate ø (n) = (p − 1)(q − 1);
4) Pick e, so that gcd(e, ø (n)) = 1, 1 < e < ø (n);
5) Calculate d, so that d · e mod ø (n) = 1, i.e., d is the multiplicative inverse of e in mod ø (n);
6) Get public key as KU = {e, n};
7) Get private key as KR = {d, n}.
Encryption
For plaintext block P < n, its ciphertext C = P^e (mod n).
Decryption
For ciphertext block C, its plaintext is P = C^d (mod n).
Code:
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
long int p,q,n,t,flag,e[100],d[100],temp[100],j,m[100],en[100],i;
char msg[100];
int prime(long int);
void ce();
long int cd(long int);
void encrypt();
void decrypt();
void main()
{
clrscr();
printf("\nENTER FIRST PRIME NUMBER\n");
scanf("%d",&p);
flag=prime(p);
if(flag==0)
{
printf("\nWRONG INPUT\n");
getch();
exit(1);
}
printf("\nENTER ANOTHER PRIME NUMBER\n");
scanf("%d",&q);
flag=prime(q);
if(flag==0||p==q)
{
printf("\nWRONG INPUT\n");
getch();
exit(1);
}
printf("\nENTER MESSAGE\n");
fflush(stdin);
scanf("%s",msg);
for(i=0;msg[i]!=NULL;i++)
m[i]=msg[i];
n=p*q;
t=(p-1)*(q-1);
ce();
printf("\nPOSSIBLE VALUES OF e AND d ARE\n");
for(i=0;i<j-1;i++)
printf("\n%ld\t%ld",e[i],d[i]);
encrypt();
decrypt();
getch();
}
int prime(long int pr)
{
int i;
j=sqrt(pr);
for(i=2;i<=j;i++)
{
if(pr%i==0)
return 0;
}
return 1;
}
void ce()
{
int k;
k=0;
for(i=2;i<t;i++)
{
if(t%i==0)
continue;
flag=prime(i);
if(flag==1&&i!=p&&i!=q)
{
e[k]=i;
flag=cd(e[k]);
if(flag>0)
{
d[k]=flag;
k++;
}
if(k==99)
break;
}
}
}
long int cd(long int x)
{
long int k=1;
while(1)
{
k=k+t;
if(k%x==0)
return(k/x);
}
}
void encrypt()
{
long int pt,ct,key=e[0],k,len;
i=0;
len=strlen(msg);
while(i!=len)
{
pt=m[i];
pt=pt-96;
k=1;
for(j=0;j<key;j++)
{
k=k*pt;
k=k%n;
}
temp[i]=k;
ct=k+96;
en[i]=ct;
i++;
}
en[i]=-1;
printf("\nTHE ENCRYPTED MESSAGE IS\n");
for(i=0;en[i]!=-1;i++)
printf("%c",en[i]);
}
void decrypt()
{
long int pt,ct,key=d[0],k;
i=0;
while(en[i]!=-1)
{
ct=temp[i];
k=1;
for(j=0;j<key;j++)
{
k=k*ct;
k=k%n;
}
pt=k+96;
m[i]=pt;
i++;
}
m[i]=-1;
printf("\nTHE DECRYPTED MESSAGE IS\n");
for(i=0;m[i]!=-1;i++)
printf("%c",m[i]);
}

Resources