I have written the code for RSA in C++ on Ubuntu. It was working fine on that, it's working fine on Windows Dev C++ as well, but it doesn't show the character properly.
Here is the code :
#include<iostream>
#include<stdlib.h> // for rand()
#include<math.h> // for floor function
#include<string.h>
using namespace std;
//function to check whether a number is prime or not
int check_prime(int number)
{
int count = 0;
for(int i = 2; i<number + 1; i++)
{
if(number%i == 0)
{
count++;
}
}
if(count>2)
{
return 0;
}
else
{
return 1;
}
}
//function to generate a random prime number
int generate_random_prime()
{
int temp;
while(1)
{
temp = rand() % 50;
if(check_prime(temp) == 1)
{
return temp;
}
}
}
int gcd(int a, int b)
{
int temp;
while(b != 0)
{
temp = b;
b = a%b;
a = temp;
}
return a;
}
// Extended Euclid GCD to find d such de congruent to 1
int extended_gcd(int a, int b)
{
int d, x, y, r, q;
if(b == 0)
{
d = a;
x = 1;
y = 0;
cout << "\n d= " << d << " x= " << x << " y= " << y << "\n";
}
int x2, x1, y2, y1;
x2 = 1;
x1 = 0;
y2 = 0;
y1 = 1;
while(b > 0)
{
q = floor(a / b);
r = a - q*b;
x = x2 - q*x1;
y = y2 - q*y1;
a = b;
b = r;
x2 = x1;
x1 = x;
y2 = y1;
y1 = y;
}
d = a;
x = x2;
y = y2;
return x2;
}
//returns a^b mod n using square and multiply method
int modular_exponentiation(int a, int b, int n)
{
if(a == 1)
{
return 0;
}
int c = 1;
for(int i = 1; i < b + 1; i++)
{
c = (c*a) % n;
}
return c;
}
//cipher text = (message^e) %n
int cipher_text(int m, int e, int n)
{
return modular_exponentiation(m, e, n);
}
//decrypted_text= (cipher^d)%n
int decrypt_cipher(int c, int d, int n)
{
return modular_exponentiation(c, d, n);
}
int main()
{
// generating two random prime p and q
int p = generate_random_prime();
int q = generate_random_prime();
cout << "Prime p : " << p << "and q : " << q << "\n";
int n = p*q;
cout << "n=p*q = " << n << "\n";
//calculating Euler Totient for prime p and q
int euler_phi = (p - 1)*(q - 1);
cout << "Euler totient is : " << euler_phi << "\n";
int d, e;
// calculating e such that 1<e<euler_phi and gcd(n,euler_phi)=1
while(1)
{
e = rand() % (euler_phi - 1 + 1) + 1;
if(gcd(euler_phi, e) == 1)
{
break;
}
}
cout << "e value is : " << e << "\n";
//calculating d such that ed congruent 1, ed=1
d = extended_gcd(e, euler_phi);
//d=5;
cout << "d value is : " << d << "\n";
//storing the message to be encrypted as char array and encrypting each char element
char message[20];
int cipher[20];
cout << "Enter the message to be encrypted : ";
cin >> message;
cout << "Message to be encrypted is : " << message << "\n";
int size = strlen(message);
//calculating cipher text c
for(int i = 0; i < size; i++)
{
cipher[i] = cipher_text(int(message[i]), e, n);
}
cout << "Cipher text is : ";
for(int i = 0; i < size; i++)
{
cout << cipher[i] << " ";
}
char message_decrypted[size];
//decrypting cipher text
for(int i = 0; i < size; i++)
{
message_decrypted[i] = decrypt_cipher(cipher[i], d, n);
}
cout << "\nDecrypted message is : ";
for(int i = 0; i < size; i++)
{
cout << message_decrypted[i];
}
cout << "\n";
return 0;
}
I have tried the code on DevC++ and using g++.
Check the images :
Image using g++ compiler
I need a way to print the char to be displayed properly.
I think that message_decrypted[i]=decrypt_cipher(cipher[i],d,n); needs to be changed to print the character properly in Devcpp
Here is the link to the code in online IDE where it works fine https://repl.it/#shubhamjohar/RSA
When your main routine invokes
decrypt_cipher(cipher[i], d, n);
cipher[0] is 386 as matching your output above. d is -179. And n is 697
The corresponding call into modular_exponentiation(a=386, b=-179, n=697) results in this for-loop getting skipped:
for (int i = 1; i<b + 1; i++) {
c = (c*a) % n;
}
Because i < (b + 1) evaluates to (1 < -178), which evaluates to false.
Therefore, your modular_exponentiation returns 1, which is an unprintable character.
Same applies for the subsequent calls to decrypt_cipher from main.
I don't know enough about the RSA algorithm to know if your implementation is correct. But when d is negative, that for-loop isn't going to do any loops.
Maybe it is incurred by the following expression in your program:
char message_decrypted[size];
There is some standard change related to this usage. please read the following page for more details.
https://www.geeksforgeeks.org/variable-length-arrays-in-c-and-c/
Or try to use something like new char[size] to allocate memory dynamically.
Related
I am trying to figure out how to print all the combinations in c++.
Given input is {"abc","xyz"} and desired output is {"ax", "ay", "az", "bx", "by", "bz", "cx", "cy","cz"}
I found this recursion code snippet :
`#include <bits/stdc++.h>
using namespace std;
void printKLengthString(char set[], string sequence, int n, int k) {
if (k == 0){
cout<<sequence<<"\t";
return;
}
for (int i = 0; i < n; i++){
string newSequence;
newSequence=sequence+set[i];
printKLengthString(set, newSequence, n, k - 1);
}
}
int main() {
char set[] = {'a', 'b'};
int n = 2;
int k = 3;
printKLengthString(set, "", n, k);
}`
but I am not able to manipulate it according to my desired inputs
Update 1:
Here is my code:
`#include <bits/stdc++.h>
using namespace std;
void printKLengthString(vector<char> set, string sequence, int n, int k) {
if (k == 0){
cout<<sequence<<"\t";
return;
}
for (int i = 0; i < n; i++){
string newSequence;
newSequence=sequence+set.at(i);
printKLengthString(set, newSequence, n, k - 1);
}
}
int main() {
vector<string> stringIn = {"ab", "xy"};
// int n = 2;
// int k = 2;
// for (int i = 0; i < set.size(); i++) {
// cout << set[i] << "\n";
// }
vector<char> set;
for (int i = 0; i < stringIn.size(); i++) {
for (int j = 0; j < stringIn[0].size(); j++) {
// cout << stringIn[i].at(j) << "\n";
// str += char(set[i].at(j));
set.push_back(stringIn[i].at(j));
}
}
// for (char k: set) {
// cout << k << "\t";
// }
cout << "\n";
// cout << "stringIn Size : " << stringIn.size() << "\n";
// cout << "set Size : " << set.size() << "\n";
int k = stringIn.size();
int n = set.size();
printKLengthString(set, "", n, k);
}`
I am getting output as :
aa ab ax ay ba bb bx by xa xb xx xy ya yb yx yy
which is permutation but I just want the combination , which I am not able to figure out..
Anyone could guide me?
Update 2: I want to scale this for multiple inputs, e.g. {"abc","def","ghi","xyz"}
const unsigned int n1 = strlen(s1);
const unsigned int n2 = strlen(s2);
for (unsigned int i1=0;i1<n1;i1++)
{
for (unsigned int i2=0;i2<n2;i2++)
{
printf("%c%c\n",s1[i1],s2[i2]);
}
}
#include <iostream>
#include <string>
using namespace std;
class Term;
class Polynomial;
class Term {
public:
friend class Polynomial;
void set_term(string s);
int get_pow();
int get_coefficient();
private:
int coefficient;
int pow;
};
class Polynomial {
public:
friend class Term;
Polynomial(int s, Term t[]);
int get_size();
Term *myterm;
private:
int P_size;
};
void Term::set_term(string s) {
coefficient = stoi(s.substr(1, 1));
pow = stoi(s.substr(4, 1));
if (s[0] == '-') {
coefficient = -coefficient;
}
}
int Term::get_coefficient() { return coefficient; }
int Term::get_pow() { return pow; }
Polynomial::Polynomial(int s, Term t[]) {
P_size = s;
myterm = new Term[s];
for (int i = 0; i < s; i++) {
myterm[i].coefficient = t[i].coefficient;
cout << i << " Term " << t[i].coefficient << endl;
cout << i << " Polynomial " << myterm[i].coefficient << endl;
myterm[i].pow = t[i].pow;
}
}
Polynomial::get_size() { return P_size; }
int main() {
string x1;
cin >> x1;
int size_x1 = x1.size();
Term term1[size_x1];
for (int i = 0; i < size_x1; i += 5) {
term1[i].set_term(x1.substr(i, 5));
}
Polynomial p1(size_x1 / 5, term1);
for (int i = 0; i < size_x1; i += 5) {
cout << term1[i].get_coefficient() << "x^";
cout << term1[i].get_pow() << endl;
}
cout << "------------------" << endl;
for (int i = 0; i < p1.get_size(); i++) {
if (p1.myterm[i].get_coefficient() > 0)
cout << "+";
cout << p1.myterm[i].get_coefficient();
cout << "x^";
cout << p1.myterm[i].get_pow() << endl;
}
return 0;
}
term1 in main is working right but when I pass it to p1(Polynomial) just t[0] and, myterm[0]
is true I mean I pass term1 to p1 as t so t[0] = term1[0] and myterm[0] = t[0]
Polynomial::Polynomial(int s, Term t[]) {
P_size = s;
myterm = new Term[s];
for (int i = 0; i < s; i++) {
myterm[i].coefficient = t[i].coefficient;
cout << i << " Term " << t[i].coefficient << endl;
cout << i << " Polynomial " << myterm[i].coefficient << endl;
myterm[i].pow = t[i].pow;
}
}
in Polynomial constructor both t[1].coeffient and, myterm[1].coefficient are 4941660(for instance)
however, t is term1 and in term1 term1[1] is the 4(for instance)
if term1[1] is 4 so t[1] should be 4 but it's not so myterm[1], is not 4 too.
There's a lot of confusion over sizes here
string x1;
cin >> x1;
int size_x1 = x1.size();
Term term1[size_x1];
for (int i = 0; i < size_x1; i += 5) {
term1[i].set_term(x1.substr(i, 5));
}
Polynomial p1(size_x1 / 5, term1);
You didn't say what your input is, but suppose it is "1234567890" then size_x1 equals 10, so term1 will also have size 10. Then your for loop will execute twice, with i equal to 0 and i equal to 5, so you will assign 12345 to term1[0] and 67890 to term1[5]. That makes no sense to me. term1 has size 10 but the only elements assigned to are zero and five.
Then you create p1 with size size_x1/5 which equals 2. So the constructor for p1 will look at term1[0] and term1[1], but in the for loop you assigned to term1[0] and term1[5].
You have to think carefully about what the code you are writing is actually doing. The compiler will do exactly what you tell it to. It's not like talking to a person who can understand what you really meant. So you have to be very careful. This is I think you really meant (but I could be wrong)
string x1;
cin >> x1;
int size_x1 = x1.size();
int size_term1 = size_x1/5;
Term term1[size_term1];
for (int i = 0; i < size_term1 ; ++i) {
term1[i].set_term(x1.substr(5*i, 5));
}
Polynomial p1(size_term1, term1);
I created a new variable size_term1 with the size of the term array, which is now the sizeof the input divided by 5. And I changed the for loop so that it assigns to term1[0] and term1[1].
So your problem has nothing to do with passing an array to a class, which you did perfectly correctly. It was not thinking clearly about the code you were writing, and making mistakes in the logic.
This is what I came up with
#include <iostream>
using namespace std;
int serialNumber = 1;
Would recursion be better?
int factorial(int n)
{
int k=1;
for(int i=1;i<=n;++i)
{
k=k*i;
}
return k;
}
How can I go about doing this in a single for loop?
Or is this the best way?
int main()
{
int a;
int b;
int c;
int fact1;
int fact2;
int fact3;
for (a=1;a < 11;a++)
{
fact1 = factorial(a);
for (b=1;b < 11;b++)
{
fact2 = factorial(b);
for (c=1;c < 11;c++)
{
fact3 = factorial(c);
cout << serialNumber << " : ";
int LHS = fact1 + fact2 + fact3;
if (LHS == a * b * c)
{
cout << "Pass:" <<" "<< a << " & " << b << " & " << c << endl;
}
else
{
cout << "Fail" <<endl;
}
serialNumber++;
}
c = 1;
}
b = 1;
}
return 0;
}
I am being forced to add more none code into it.
Thanks for the help!
Don't know if this is helps,but>
check for minimum of A,B,C
A!+B!+C! = (min(A,B,C)!)*(1+((min+1..restfact1)!)+((min+1..restfact2)!))
So, you can calculate the minimum factorial and than re-use it for calculating others.
On the other hand, you can calculate only the maximum factorial and store its results in the array, and re-use pre-calculated values for finding factorial of smaller numbers
Other implication is that the minimum number can be reduced
restfact1 * restfact2 = ((min-1)!)*(1+((min+1..restfact1)!)+((min+1..restfact2)!))
Part of the question was how can this be done in a single loop and this is one way to do that.
I don't think this is a better way of doing it, but the question was asked:
constexpr int bound = 10;
int Factorials[bound + 1];
for (int i = 1; i <= bound; ++i) Factorials[i] = Factorial(i);
for (int i = 0; i < bound * bound * bound; ++i) {
int s = i + 1;
int a = i;
int c = 1 + a % bound;
a /= bound;
int b = 1 + a % bound;
a /= bound;
++a;
cout << s << " : ";
int LHS = Factorials[a] + Factorials[b] + Factorials[c];
if (LHS == a * b * c)
...
}
I made a simple recursion program for this question http://www.spoj.com/problems/COINS/, but whenever recursion happens my class variables lose their value and store the value from the recursion loop.
Here's the code:
#include<iostream>
using namespace std;
class a
{
public:
int c = 0, d = 0, b = 0, x = 0;
int recur(int n)
{
b = (n / 2);
if (b >= 12)
{
b = recur(b);
}
c = (n / 3);
if (c >= 12)
{
c = recur(c);
}
d = (n / 4);
if (d >= 12)
{
d = recur(d);
}
x = b + c + d;
return x;
}
};
int main()
{
int n;
while(cin)
{
cin >> n;
int b = 0, r = 0;
a abc;
r = (n > abc.recur(n)) ? (n) : (abc.recur(n));
cout << r << endl;
}
return 0;
}
So for input 12, I'll be getting 13 but for the input value of 44 I'm getting 44.
This could be a working solution:
#include <iostream>
using namespace std;
int changeToDollars(int bytelandians) {
int byTwo = bytelandians / 2;
int byThree = bytelandians / 3;
int byFour = bytelandians / 4;
int sum = byTwo + byThree + byFour;
if (sum < bytelandians) {
return bytelandians;
} else {
return changeToDollars(byTwo) + changeToDollars(byThree) + changeToDollars(byFour);
}
}
int main() {
int bytelandians;
cout << "How much bytelandians?: ";
while (cin >> bytelandians) {
cout << "Corresponding $: " << changeToDollars(bytelandians) << endl;
cout << "How much bytelandians?: ";
}
return 0;
}
The changeToDollars function, using a simple recursive algorithm, exchanges each single Byteland coin into the corresponding three ones with minor value, until the overall converted amount is advantageous.
void CensusData::mergeSort(int type) {
if(type == 0)
MERGE_SORT(type, 0, data.size());
}
void CensusData::MERGE_SORT(int type, int p, int r){
//int q;
//cout << "data size " << data.size() << endl;
std::cout << "MERGE_SORT START ///("<< p << ", " << r << ")" <<std::endl;
if(p < r)
{
int q = (p + r)/2;
MERGE_SORT(type, p, q);
MERGE_SORT(type, q + 1, r);
MERGE(type, p, q ,r);
}
}
void CensusData::MERGE(int type, int p, int q, int r){
if(type == 0)
{
std::cout << "MERGING" << std::endl;
//int n1;
//int n2;
int n1 = q - p + 1;
int n2 = r - q;
int L[n1 + 1];
int R[n2 + 1];
for(int i = 1; i < n1; i++)
{
cout << "filling Left Array" << endl;
L[i] = data[p + i - 1]->population;
}
for(int j = 1; j < n2; j++)
{
cout << "filling Right Array" << endl;
R[j] = data[q + j]->population;
}
int i = 1;
int j = 1;
for(int k = p; p < r; p++)
{
cout << "for loop: " << endl;
if(L[i] <= R[j])
{
cout << "TRUE" << endl;
data[k]->population = L[j];
i = i + 1;
}
/*else if(data[k]->population == R[j])
{
cout << "FALSE" << endl;
j = j + 1;
}*/
else
{
data[k]->population = R[j];
j = j + 1;
}
}
}
}
do not worry about type, it wont effect this program at all. basically i am trying to make a merge sort that will take a vector containing an integer, the vector looks like this:
class Record { // declaration of a Record
public:
std::string* city;
std::string* state;
int population;
Record(std::string&, std::string&, int);
~Record();
};
std::vector<Record*> data;
basically i have been trying to get it to actually sort, but it doesn't seem to work at all, i have even seen garbage in the program.
example input:
237 812826 68642
output:
4484540 812826 68642
Note: all of the rest of the program works fine (tested it with an insertion sort) only this part is not working.
Take a look at lecture 15 of the excellent Stanford Universities course Programming Abstractions. It covers all kinds of sorts including merge:
http://see.stanford.edu/see/lecturelist.aspx?coll=11f4f422-5670-4b4c-889c-008262e09e4e
You can even get the source code from SourceForge:
http://sourceforge.net/projects/progabstrlib/files/