Very new to "backend" and trying out this reddit challenge that I saw at r/dailyprogrammer
Challenge:
Assign every lowercase letter a value, from 1 for a to 26 for z. Given a string of lowercase letters, find the sum of the values of the letters in the string.
I specifically want to do it like this but is it possible? How can a user input a word that would then add the int I've listed here so that the total sum of the word would show.
int main()
{
int a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
a=1;
b=2;
c=3;
d=4;
e=5;
f=6;
g=7;
h=8;
i=9;
j=10;
k=11;
l=12;
m=13;
n=14;
o=15;
p=16;
q=17;
r=18;
s=19;
t=20;
u=21;
v=22;
w=23;
x=24;
y=25;
z=26;
This is pretty much one function call in C++
std::string example = "example";
std::cout << std::accumulate(example.begin(), example.end(), 0,
[](int sum, char c) { return sum + (c - 'a' + 1); }
);
std::accumulate adds things in a collection. Usually, it just uses '+' but in this case I use a custom adder [](int sum, char c) { return sum + (c - 'a' + 1); }. This adds not the ASCII value of c, but (c - 'a' + 1). If c=='a', then c-'a'==0 and (c - 'a' + 1)==1
ok , so , this is my code and it's working ... explanation -- >
we know storing a charachter in a int variable will store the ASCII value , the ASCII value of a is 97 , b is 98 so on .... subtracting 96 from each letter's ascii value will give the number you want -->
if you are still confused about the ascii table then go look it up at the google you'll understand
#include <iostream>
#include <string>
using namespace std;
int main(){
string str ;
cin >> str;
int value = 0;
for(int i=0 ; i<str.length() ; i++){
int v = str[i] - 96;
value += v;
}
cout << value;
return 0;
}
make use of the std::map<char,int>
int main(void)
{
std::map<std::string,int> list;
char letter = 'a';
int val = 1;
while(val <= 26)
{
list.insert(std::make_pair(letter,val));
letter++;
val++;
}
}
You're confusing the concept of strings and characters with a variable's name.
// a is the variable name, this is information for the programmer
int a = 1;
// 'a' here is the actual letter a, things can actually be done with this in the program
char theLetterA = 'a';
Combine this concept with std::cin so that you can read data from the user and you are on your way to figuring this out.
See:
https://www.cplusplus.com/doc/tutorial/basic_io/
https://www.w3schools.com/cpp/cpp_data_types_char.asp
https://www.w3schools.com/cpp/cpp_data_types.asp
Related
I have a vector declared containing n integers.
vector <int> tostore[n];
I want to store all the numbers in the vector inside a string in the format of their subscripts, like 12345..n
Example:
vector <int> store_vec{1,2,3,4,5};
int store_str; //to store the digits in order from vector store_vec
cout<<store_str;
Desired Output:
12345
How do I store it in store_str without printing it?
Instead of using an integer, which if it is 32 bits wide will only be able to store 8-9 digits, you could instead build a string that has all of the elements combined like
vector <int> store_vec{1,2,3,4,5};
std::string merged;
merged.reserve(store_vec.size());
for (auto num : store_vec)
merged += '0' + num;
// now merged is "12345"
One way would be to just multiply by 10 each iteration
int result = 0;
for (auto it : tostore)
{
result = result * 10 + it;
}
As mentioned in comments, a more robust approach would be concatenating to an actual string, or at least using a 64-bit integer.
Since you confirmed that store_vec only contains single digit numbers, a simple way of doing this would be :
std::vector<uint8_t> store_vec = {1,2,3,4,5};
std::string str = std::accumulate(store_vec.begin(), store_vec.end(), std::string{},
[](const std::string& res, uint8_t num){ return res + char('0' + num); });
int resnum = atoi(str.c_str());
or basically use the str resulting with accumulate since it already represent the sequence.
Since you know that each value in tostore will only be a single digit, you could use int_8 or uint8_t data types to store the values instead. This way you can still perform arithmetic on the values within the vectors (so long as the result of the arithmetic falls within the range of -128 to 127 or 0 to 255 respectively, see integer types for more details). These data types have the advantage of being only a single byte long, allowing your vector to potentially be more densely packed and faster to traverse. You can then use std::cout << unsigned(tostore[n]) to cast the integer into a character for display. The whole thing would look something like this
#include <iostream>
#include <type_traits>
#include <vector>
int main()
{
std::vector<uint8_t> tostore;
tostore.reserve(32);
for(int i = 0; i < 32; ++i) {
tostore.push_back(i % 10);
}
for(uint i = 0; i < tostore.size(); ++i) {
std::cout << unsigned(tostore[i]);
}
}
Alternatively, if you know that your digit will always be positive it opens a whole new range of possibilities. When converting an integer to a list of characters a program needs to break the integer into its individual digits and then add 48 to that digits value to find its ascii character code equivalent (see asciiTable for more details). The process of splitting the integer into its base 10 digits may be too cumbersome (you decide) if you plan to display these characters often or perform only a few arithmetic operations on the data. In this case you could create a struct that stores the value of the integer as a char data type but performs arithmetic with the data as if it were an integer. This way, when printing the values no operations need to be performed to format the data properly and the only operations that need to be done to format the data for arithmetic operations are simple subtractions by 48 which are very fast. Such a struct could look something like this:
#include <iostream>
#include <type_traits>
#include <vector>
struct notANumber {
char data;
notANumber() {}
notANumber(const int& a) : data(a + 48) {}
notANumber(const char& a) : data(a) {}
notANumber operator+(const notANumber& b) {
notANumber c;
c.data = b.data + c.data - 48;
return c;
}
notANumber operator-(const notANumber& b) {
notANumber c;
c.data = b.data - c.data + 48;
return c;
}
notANumber operator*(const notANumber& b) {
notANumber c;
c.data = (b.data - 48) * (c.data - 48) + 48;
return c;
}
notANumber operator/(const notANumber& b) {
notANumber c;
c.data = (b.data - 48) / (c.data - 48) + 48;
return c;
}
};
int operator+(const int& a, const notANumber& b) {
int c;
c = a + b.data - 48;
return c;
}
int operator-(const int& a, const notANumber& b) {
int c;
c = a - b.data + 48;
return c;
}
int operator*(const int& a, const notANumber& b) {
int c;
c = a * (b.data - 48);
return c;
}
int operator/(const int& a, const notANumber& b) {
int c;
c = a / (b.data - 48);
return c;
}
int main()
{
std::vector<notANumber> tostore;
tostore.reserve(32);
for(int i = 0; i < 32; ++i) {
tostore.push_back(i % 10);
}
std::cout.write(reinterpret_cast<char*>(tostore.data()), tostore.size());
}
Now this might not be what you are looking for, but I hope that it does showcase an important aspect of programming which is "the more you know about the data you are working with, the more you can optimize the program" so make sure you have a good feel for the range of the data you are working with and what operations you are going to be doing with it most often (arithmetic or printing for example) and the cost of those operations.
I have to input a number n, an a digit and a b digit and output the number n with all the a digits in it replaced by a b one. For example:
Input:
n = 1561525
a = 5
b = 9
Output:
n = 1961929
Should be recursive ! I didn't post any code as I've done it in a non-recursive way but apparently it's not even close to what I need.
Thanks for the help !
Check this, it works but maybe it is to much C
int convert(int num, int a, int b)
{
if( num )
{
int res = convert(num/10,a,b);
int t = num%10;
res *=10;
t = t == a ? b:t;
res = res + t;
return res;
}
return 0;
}
Divide by 10 the initial number, until nothing left of it, and then construct it again replacing a with b.
To make things easier, you can convert the number into a string (a char[] in C++). Then, it's a simple matter of iterating over it and checking at each step if the number we want to replace was found in the current position. For a possible solution, here's an implementation of the algorithm in Python - one of the nice things of the language is that it reads almost as pseudocode, and it should be relatively simple to port to C++:
def aux(n, a, b, i):
if i == len(n):
return ''
elif n[i] == a:
return b + aux(n, a, b, i+1)
else:
return n[i] + aux(n, a, b, i+1)
def change(n, a, b):
return int(aux(str(n), str(a), str(b), 0))
It works as expected:
change(1561525, 5, 9)
=> 1961929
So the easiest and safest way I can think of, is by using std::replace:
int replace(int num, int d1, int d2) {
string s = std::to_string(num); // convert to string
std::replace( s.begin(), s.end(), d1+'0', d2+'0'); // call std::replace
return atoi( s.c_str() ); // return the int
}
Now if you really have to use recursion (there is no need for it here), here's one possible solution:
using std::string;
// recursive function, accepts a string, current index, c2 replaces c1
string replace_rec (string s, unsigned index, char c1, char c2) {
// check if the it's still a valid index
if (index < s.size()) {
// if this is a char to be converted, do so
if (s[index] == c1)
s[index] = c2;
// call itself but with an updated string and incremented index
replace_rec(s, index+1, c1, c2);
}
// the last call will result in the string with all chars checked. return it
return s;
}
// call this function with input, the num to be replaced and what with
int replace(int num, int d1, int d2) {
string s = std::to_string(num); // convert to string
// convert the result back to int and return it.
return atoi( replace_rec(s, 0, d1+'0', d2+'0').c_str() );
}
In any case, you can call your replace() function like this:
int main(){
cout << replace (4578, 4, 9); // output: 9578
cin.get();
}
I am doing a factorial program with strings because i need the factorial of Numbers greater than 250
I intent with:
string factorial(int n){
string fact="1";
for(int i=2; i<=n; i++){
b=atoi(fact)*n;
}
}
But the problem is that atoi not works. How can i convert my string in a integer.
And The most important Do I want to know if the program of this way will work with the factorial of 400 for example?
Not sure why you are trying to use string. Probably to save some space by not using integer vector? This is my solution by using integer vector to store factorial and print.Works well with 400 or any large number for that matter!
//Factorial of a big number
#include<iostream>
#include<vector>
using namespace std;
int main(){
int num;
cout<<"Enter the number :";
cin>>num;
vector<int> res;
res.push_back(1);
int carry=0;
for(int i=2;i<=num;i++){
for(int j=0;j<res.size();j++){
int tmp=res[j]*i;
res[j]=(tmp+carry)%10 ;
carry=(tmp+carry)/10;
}
while(carry!=0){
res.push_back(carry%10);
carry=carry/10;
}
}
for(int i=res.size()-1;i>=0;i--) cout<<res[i];
cout<<endl;
return 0;
}
Enter the number :400
Factorial of 400 :64034522846623895262347970319503005850702583026002959458684445942802397169186831436278478647463264676294350575035856810848298162883517435228961988646802997937341654150838162426461942352307046244325015114448670890662773914918117331955996440709549671345290477020322434911210797593280795101545372667251627877890009349763765710326350331533965349868386831339352024373788157786791506311858702618270169819740062983025308591298346162272304558339520759611505302236086810433297255194852674432232438669948422404232599805551610635942376961399231917134063858996537970147827206606320217379472010321356624613809077942304597360699567595836096158715129913822286578579549361617654480453222007825818400848436415591229454275384803558374518022675900061399560145595206127211192918105032491008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
There's a web site that will calculate factorials for you: http://www.nitrxgen.net/factorialcalc.php. It reports:
The resulting factorial of 250! is 493 digits long.
The result also contains 62 trailing zeroes (which constitutes to 12.58% of the whole number)
3232856260909107732320814552024368470994843717673780666747942427112823747555111209488817915371028199450928507353189432926730931712808990822791030279071281921676527240189264733218041186261006832925365133678939089569935713530175040513178760077247933065402339006164825552248819436572586057399222641254832982204849137721776650641276858807153128978777672951913990844377478702589172973255150283241787320658188482062478582659808848825548800000000000000000000000000000000000000000000000000000000000000
Many systems using C++ double only work up to 1E+308 or thereabouts; the value of 250! is too large to store in such numbers.
Consequently, you'll need to use some sort of multi-precision arithmetic library, either of your own devising using C++ string values, or using some other widely-used multi-precision library (GNU GMP for example).
The code below uses unsigned double long to calculate very large digits.
#include<iostream.h>
int main()
{
long k=1;
while(k!=0)
{
cout<<"\nLarge Factorial Calculator\n\n";
cout<<"Enter a number be calculated:";
cin>>k;
if (k<=33)
{
unsigned double long fact=1;
fact=1;
for(int b=k;b>=1;b--)
{
fact=fact*b;
}
cout<<"\nThe factorial of "<<k<<" is "<<fact<<"\n";
}
else
{
int numArr[10000];
int total,rem=0,count;
register int i;
//int i;
for(i=0;i<10000;i++)
numArr[i]=0;
numArr[10000]=1;
for(count=2;count<=k;count++)
{
while(i>0)
{
total=numArr[i]*count+rem;
rem=0;
if(total>9)
{
numArr[i]=total%10;
rem=total/10;
}
else
{
numArr[i]=total;
}
i--;
}
rem=0;
total=0;
i=10000;
}
cout<<"The factorial of "<<k<<" is \n\n";
for(i=0;i<10000;i++)
{
if(numArr[i]!=0 || count==1)
{
cout<<numArr[i];
count=1;
}
}
cout<<endl;
}
cout<<"\n\n";
}//while
return 0;
}
Output:
![Large Factorial Calculator
Enter a number be calculated:250
The factorial of 250 is
32328562609091077323208145520243684709948437176737806667479424271128237475551112
09488817915371028199450928507353189432926730931712808990822791030279071281921676
52724018926473321804118626100683292536513367893908956993571353017504051317876007
72479330654023390061648255522488194365725860573992226412548329822048491377217766
50641276858807153128978777672951913990844377478702589172973255150283241787320658
18848206247858265980884882554880000000000000000000000000000000000000000000000000
000000000000][1]
You can make atoi compile by adding c_str(), but it will be a long way to go till getting factorial. Currently you have no b around. And if you had, you still multiply int by int. So even if you eventually convert that to string before return, your range is still limited. Until you start to actually do multiplication with ASCII or use a bignum library there's no point to have string around.
Your factorial depends on conversion to int, which will overflow pretty fast, so you want be able to compute large factorials that way. To properly implement computation on big numbers you need to implement logic as for computation on paper, rules that you were tought in primary school, but treat long long ints as "atoms", not individual digits. And don't do it on strings, it would be painfully slow and full of nasty conversions
If you are going to solve factorial for numbers larger than around 12, you need a different approach than using atoi, since that just gives you a 32-bit integer, and no matter what you do, you are not going to get more than 2 billion (give or take) out of that. Even if you double the size of the number, you'll only get to about 20 or 21.
It's not that hard (relatively speaking) to write a string multiplication routine that takes a small(ish) number and multiplies each digit and ripples the results through to the the number (start from the back of the number, and fill it up).
Here's my obfuscated code - it is intentionally written such that you can't just take it and hand in as school homework, but it appears to work (matches the number in Jonathan Leffler's answer), and works up to (at least) 20000! [subject to enough memory].
std::string operator*(const std::string &s, int x)
{
int l = (int)s.length();
std::string r;
r.resize(l);
std::fill(r.begin(), r.end(), '0');
int b = 0;
int e = ~b;
const int c = 10;
for(int i = l+e; i != e;)
{
int d = (s[i]-0x30) * x, p = i + b;
while (d && p > e)
{
int t = r[p] - 0x30 + (d % c);
r[p] = (t % c) + 0x30;
d = t / c + d / c;
p--;
}
while (d)
{
r = static_cast<char>((d % c) +0x30)+r;
d /= c;
b++;
}
i--;
}
return r;
}
In C++, the largest integer type is 'long long', and it hold 64 bits of memory, so obviously you can't store 250! in an integer type. It is a clever idea to use strings, but what you are basically doing with your code is (I have never used the atoi() function, so I don't know if it even works with strings larger than 1 character, but it doesn't matter):
covert the string to integer (a string that if this code worked well, in one moment contains the value of 249!)
multiply the value of the string
So, after you are done multiplying, you don't even convert the integer back to string. And even if you did that, at one moment when you convert the string back to an integer, your program will crash, because the integer won't be able to hold the value of the string.
My suggestion is, to use some class for big integers. Unfortunately, there isn't one available in C++, so you'll have to code it by yourself or find one on the internet. But, don't worry, even if you code it by yourself, if you think a little, you'll see it's not that hard. You can even use your idea with the strings, which, even tough is not the best approach, for this problem, will still yield the results in the desired time not using too much memory.
This is a typical high precision problem.
You can use an array of unsigned long long instead of string.
like this:
struct node
{
unsigned long long digit[100000];
}
It should be faster than string.
But You still can use string unless you are urgent.
It may take you a few days to calculate 10000!.
I like use string because it is easy to write.
#include <bits/stdc++.h>
#pragma GCC optimize (2)
using namespace std;
const int MAXN = 90;
int n, m;
int a[MAXN];
string base[MAXN], f[MAXN][MAXN];
string sum, ans;
template <typename _T>
void Swap(_T &a, _T &b)
{
_T temp;
temp = a;
a = b;
b = temp;
}
string operator + (string s1, string s2)
{
string ret;
int digit, up = 0;
int len1 = s1.length(), len2 = s2.length();
if (len1 < len2) Swap(s1, s2), Swap(len1, len2);
while(len2 < len1) s2 = '0' + s2, len2++;
for (int i = len1 - 1; i >= 0; i--)
{
digit = s1[i] + s2[i] - '0' - '0' + up; up = 0;
if (digit >= 10) up = digit / 10, digit %= 10;
ret = char(digit + '0') + ret;
}
if (up) ret = char(up + '0') + ret;
return ret;
}
string operator * (string str, int p)
{
string ret = "0", f; int digit, mul;
int len = str.length();
for (int i = len - 1; i >= 0; i--)
{
f = "";
digit = str[i] - '0';
mul = p * digit;
while(mul)
{
digit = mul % 10 , mul /= 10;
f = char(digit + '0') + f;
}
for (int j = 1; j < len - i; j++) f = f + '0';
ret = ret + f;
}
return ret;
}
int main()
{
freopen("factorial.out", "w", stdout);
string ans = "1";
for (int i = 1; i <= 5000; i++)
{
ans = ans * i;
cout << i << "! = " << ans << endl;
}
return 0;
}
Actually, I know where the problem raised At the point where we multiply , there is the actual problem ,when numbers get multiplied and get bigger and bigger.
this code is tested and is giving the correct result.
#include <bits/stdc++.h>
using namespace std;
#define mod 72057594037927936 // 2^56 (17 digits)
// #define mod 18446744073709551616 // 2^64 (20 digits) Not supported
long long int prod_uint64(long long int x, long long int y)
{
return x * y % mod;
}
int main()
{
long long int n=14, s = 1;
while (n != 1)
{
s = prod_uint64(s , n) ;
n--;
}
}
Expexted output for 14! = 87178291200
The logic should be:
unsigned int factorial(int n)
{
unsigned int b=1;
for(int i=2; i<=n; i++){
b=b*n;
}
return b;
}
However b may get overflowed. So you may use a bigger integral type.
Or you can use float type which is inaccurate but can hold much bigger numbers.
But it seems none of the built-in types are big enough.
I have what is hopefully a very easy question, I just cant find the answer online. I made a merge sort function ( which im sure has inefficiencies), but im here to ask about the threads. I'm using Windows' CreateThread function to spawn threads to sort intervals of a given array. Once all the threads are finished, I will merge the segments together for the final result. I havent implemented the final merge yet because im getting strange errors which im sure is from a dumb mistake in the threads. I'll post my code, if you could kindly look at paraMSort. Ill post the whole MergeSort.h file so you can see the helper functions as well. Sometimes the code will compile and run perfectly. Sometimes the console will abruptly close with no errors/exceptions. There shouldnt be mutex issues because im doing operations on different segments of the array (Different memory locations altogether). Does anyone see something wrong? Thanks so much.
PS. Are Windows CreateThread's kernel level? In other words, if I make 2 threads on a dual core computer, may they run simultaneously on separate cores? Im thinking yes, since on this computer I can do the same work in 1/2 the time with 2 threads (with another test example).
PPS. I also saw some parallelism answers solved using Boost.Thread. Should I just use boost threads instead of windows threads? I don't have experience with Boost.
#include "Windows.h"
#include <iostream>
using namespace std;
void insert_sort(int* A, int sA, int eA, int* B, int sB, int eB)
{
int value;
int iterator;
for(int i = sA + 1; i < eA; i++)
{
value = A[i]; // Grab the next value in the array
iterator = i - 1;
// Move this value left up the list until its in the right spot
while(iterator >= sA && value < A[iterator])
A[iterator + 1] = A[iterator--];
A[iterator + 1] = value; // Put value in its correct spot
}
for(int i = sA; i < eB; i++)
{
B[i] = A[i]; // Put results in B
}
}
void merge_func(int* a, int sa, int ea, int* b, int sb, int eb, int* c, int sc)
{
int i = sa, j = sb, k = sc;
while(i < ea && j < eb)
c[k++] = a[i] < b[j] ? a[i++] : b[j++];
while(i < ea)
c[k++] = a[i++];
while(j < eb)
c[k++] = b[j++];
}
void msort_big(int* a, int* b, int s, int e, bool inA)
{
if(e-s < 4)
{
insert_sort(a, s, e, b, s, e);
return; // We sorted (A,s,e) into (B,s,e).
}
int m = (s + e)/2;
msort_big(a, b, s, m, !inA);
msort_big(a, b, m, e, !inA);
// If we want to merge in A, do it. Otherwise, merge in B
inA ? merge_func(b, s, m, b, m, e, a, s) : merge_func(a, s, m, a, m, e, b, s);
}
void msort(int* toBeSorted, int s, int e)
// Sorts toBeSorted from [s, e+1), so just enter [s, e] and
// the call to msort_big adds one.
{
int* b = new int[e - s + 1];
msort_big(toBeSorted, b, s, e+1, true);
delete [] b;
}
template <class T>
struct SortData_Send
{
T* data;
int start;
int end;
};
DWORD WINAPI msort_para_callback(LPVOID lpParam)
{
SortData_Send<int> dat = *(SortData_Send<int>*)lpParam;
msort(dat.data, dat.start, dat.end);
cout << "done! " << endl;
}
int ceiling_func(double num)
{
int temp = (int)num;
if(num > (double)temp)
{
return temp + 1;
}
else
{
return temp;
}
}
void paraMSort(int* toBeSorted, int s, int e, int numThreads)
{
HANDLE threads[numThreads];
DWORD threadIDs[numThreads];
SortData_Send<int>* sent[numThreads];
for(int i = 0; i < numThreads; i++)
{
// So for each thread, make an interval and pass the pointer to the array of ints.
// So for numThreads = 3 and array size of 0 to 99 (100), we have 0-32, 33-65, 66-100.
// 100 because sort function takes [start, end).
sent[i] = new SortData_Send<int>;
sent[i]->data = toBeSorted;
sent[i]->start = s + ceiling_func(double(i)*(double)e/double(numThreads));
sent[i]->end = ceiling_func(double(i+1)*double(e)/double(numThreads)) + ((i == numThreads-1) ? 1 : -1);
threads[i] = CreateThread(NULL, 0, msort_para_callback, sent[i], 0, &threadIDs[i]);
}
WaitForMultipleObjects(numThreads, threads, true, INFINITE);
cout << "Done waiting!" <<endl;
}
Assuming 's' is your starting point and 'e' is your ending point for a thread shouldn't your code be something like
sent[i]->start = s + ceiling_func(double(i)*(double)(e-s)/double(numThreads));
sent[i]->end = (i == numThreads-1) ? e : (s - 1 + ceiling_func(double(i+1)*(double)(e-s)/double(numThreads)));
This is in case your function void paraMSort(int* toBeSorted, int s, int e, int numThreads) is being called with a value of 's' not equal to 0? This could cause you to read wrong sections of memory.
I'm trying to implement a simple RSA encryption/decryption process, and I'm pretty sure I've got the equations around the right way. Although it doesn't seem to be printing out the correct decrypted value after the encryption. Any ideas?.
//test program
#include <iostream>
#include <string.h>
#include <math.h>
using namespace std;
int gcd(int a, int b);
int main(){
char character = 'A'; //character that is to be encrypted
int p = 7;
int q = 5;
int e = 0; // just initializing to 0, assigning actual e value in the 1st for loop
int n = p*q;
int phi = (p-1)*(q-1);
int d = 0; // " " 2nd for loop
//---------------------------finding 'e' with phi. where "1 < e < phi(n)"
for (int i=2; i < phi; i++){
if (gcd(i,phi) == 1){ //if gcd is 1
e = i;
break;
}
}
//----------------------------
//---------------------------finding 'd'
for (int i = 2; i < phi; i++){
int temp = (e*i)%phi;
if (temp == 1){
d = i;
break;
}
}
printf("n:%d , e:%d , phi:%d , d:%d \n",n,e,phi,d);
printf("\npublic key is:[%d,%d]\n",e,n);
printf("private key is:[%d,%d]\n",d,n);
int m = static_cast<int>(character); //converting to a number
printf("\nconverted character num:%d\n",m);
//Encryption part ie. c = m^e MOD n
int power = pow(m,e); // m^e
int c = power%n; // c = m^e MOD n. ie. encrypted character
printf("\n\nEncrypted character number:%d\n",c);
//decryption part, ie. m = c^d MOD n
power = pow(c,d);
int m2 = power%n;
printf("\n\ndecrypted character number:%d\n",m2);
return 0;
}
int gcd(int a, int b){
int r;
if (a < 0) a = -a;
if (b < 0) b = -b;
if (b > a) {
r = b; b = a; a = r;
}
while (b > 0) {
r = a % b;
a = b;
b = r;
}
return a;
}
(The prime numbers being used are 5 and 7, for the test)
Here I'm converting the character 'A' to its numeric value which is of course 65. When I encrypt this value using c = m^e MOD n (where m is the converted value, i.e. 65) it gives me c as 25.
Now, to reverse the process, I do m = c^d MOD n, which gives me m as 30 ... which really isn't correct because it should be 65, no?
Where exactly have I gone wrong?
[edit]
Is my calculation of d correct?
The encrypted message m must be less than n. You can't use values larger than n, because the calculations are done modulo n. In your case m=65 and n=35. So you are actually getting the correct answer modulo n, because 65 % 35 == 30.
It is caused by having m greater than or equal to n like #interjay already answered.
But I found another problem with your code, my gcc4.1.2 compiler output 24 for the encrypted value not 25. It is because you use pow() function and then convert the result (which is type double) to int that causes precision loss.
Don't use pow() function, instead use square and multiply modulo n algorithm to compute c = m^e MOD n and m = c^d MOD n. It is faster than pow() and you won't need to unsafely downcast the result to integer.