Convert decimal to binary in big number - c++

I want to create a big number with 128 bit.
When I convert the string decimal to binary and set bit to the new data QInt :__int64 a[2], it only true for a small number (about 10 digits).
This is my code: http://codepad.org/HmYqMQme
#include<iostream>
#include<stdio.h>
#include<string>
using namespace std;
//new data
class QInt
{
private:
__int64 a[2];
public:
void Get()
{
cout << a[0] << endl;
cout << a[1] << endl;
}
QInt()
{
a[0] = 0;
a[1] = 0;
}
//the funtion get the string binary of a[1]
char* GetQInt(char *A);
//the devide two of string decimal
char* Div2(char *Str);
//the funtion set bit to a[0] and a[1]
void Setbit(int i, int bit);
//con vert decimal to binary
QInt ConvertDecimalToBinary(char *De, char *Bi);
};
//the funtion get the string binary of a[1]
char *QInt::GetQInt(char *A)
{
for (int i = 0; i < 64; i++)
{
if (((a[1] >> i) & 1) != 0)
{
A[63 - i] = 49;
}
else
{
A[63 - i] = 48;
}
}
return A;
}
// the funtion set bit to a[0] and a[1]
void QInt:: Setbit(int i, int bit)
{
//if i<64 we set bit to a[1]
if (i < 64)
{
if (bit==1)
{
a[1]=(1 << i) | a[1];
}
}//similar to a[1]
else
{
if (bit == 1)
a[0]=(1 << i) | a[0];
}
}
//the devide two of string decimal
char*QInt:: Div2(char *Str)
{
char Arr[100];
int n = strlen(Str);
int a = 0;//lay phan du
int i = 0;
int j = 0;
while (Str[i] == 0)
{
i++;
}
for (i; i < n; i++)
{
int c = Str[i] - 48 + a * 10;
a = c % 2;
Arr[j] = c / 2 + 48;
j++;
}
Arr[i] = '\0';
for (i = 0; i < strlen(Arr); i++)
{
Str[i] = Arr[i];
}
Str[i] = '\0';
return Str;
}
//con vert decimal to binary
QInt QInt::ConvertDecimalToBinary(char *De,char *Bi)
{
int bit;
int i = 127;
int lenth = strlen(De);
while (1)
{
//variable h use to count the number 0 of the string decimal,if h=lenth,exit
int k = 0;
int h = 0;
while (De[k])
{
if (De[k] == '0')
h++;
k++;
}
if (h == lenth)
break;
else
{
bit = (De[lenth - 1] - 48) % 2;
Bi[i] = bit + 48;
Setbit(127 - i, bit);
De = Div2(De);
i--;
}
}
Bi[128] = NULL;
return *this;
}
int main()
{
char s[100];
char b[200];
char c[200];
for (int i = 0; i < 128; i++)
{
b[i] = 48;
}
cout << "Please enter a string : ";
gets_s(s, 99);
QInt a;
a.ConvertDecimalToBinary(s, b);
a.Get();
a.GetQInt(c);
for (int i = 0; i < 64; i++)
cout << b[i];
cout << endl;
for (int i = 64; i < 128; i++)
cout << b[i];
cout << endl;
for (int i = 0; i < 64; i++)
{
cout << c[i];
}
cout << endl;
system("pause");
return 0;
}

If i==100, what do you think (1 << i) does? What should it do? And why are you ignoring a[0] in GetQInt ?
In general, you have quite a few problems. You're not comfortable with std::string, and making a mess of the char* everywhere. You're not clearly articulating (not even to yourself) what methods are supposed to be doing. You're putting mathods in a class that are unrelated to the class. Even worse, some of those methods redefine the name a ! That is very confusing.

Related

Why the simple multiplication would result in some garbled characters?

I try to design a program that implements the multiplication between two big integers(Using C++). But after I complete it, I found that if I input the two integers by the command arguments, the results would be sometimes very weird and sometimes right. Please help me figure out the reason and tell me how to fix it. Thanks (The main function that implements the function of multiplication between two big integers is mul() ).
#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;
void mul(char *c1, char *c2, int len1, int len2);
void printArr(char *c1, char *c2, int len1, int len2);
int main(int argc, char **argv)
{
if (argv[1] != NULL)
{
char cArr1[500], cArr2[500];
for (int i = 0; i < strlen(argv[1]); i++)
{
cArr1[i] = argv[1][i];
}
for (int i = 0; i < strlen(argv[2]); i++)
{
cArr2[i] = argv[2][i];
}
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
exit(100);
}
while (true)
{
cout << "Please input two integers" << endl;
char cArr1[500], cArr2[500];
cin >> cArr1;
if (cArr1[0] == 'q' && cArr1[1] == 'u' && cArr1[2] == 'i' && cArr1[3] == 't')
{
exit(1000);
}
cin >> cArr2;
int parity = 0;
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
if (cArr1[0] == '-')
{
for (int i = 1; i < len1; i++)
{
cArr1[i - 1] = cArr1[i];
}
parity++;
len1--;
}
if (cArr2[0] == '-')
{
for (int i = 1; i < len2; i++)
{
cArr2[i - 1] = cArr2[i];
}
parity++;
len2--;
}
bool isDigit = true;
for (int i = 0; i < len1; i++)
{
if (!isdigit(cArr1[i]))
{
isDigit = false;
}
}
for (int i = 0; i < len2; i++)
{
if (!isdigit(cArr2[i]))
{
isDigit = false;
}
}
if (!isDigit)
{
cout << "\rInvalid input. Try again" << endl;
continue;
}
if (parity % 2 != 0)
{
cout << "-";
}
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
}
}
void mul(char *bigger, char *smaller, int bigLen, int smallLen)
{
int *bigNum = new int[bigLen];
int *smallNum = new int[smallLen];
for (int i = 0; i < bigLen; i++)
{
bigNum[i] = bigger[bigLen - i - 1] - '0';
}
for (int i = 0; i < smallLen; i++)
{
smallNum[i] = smaller[smallLen - i - 1] - '0';
}
int res[30];
for (int i = 0; i < 30; i++)
{
res[i] = 0;
}
for (int i = 0; i < smallLen; i++)
{
for (int j = 0; j < bigLen; j++)
{
res[i + j] += bigNum[j] * smallNum[i];
}
}
for (int i = 0; i < bigLen + smallLen; i++)
{
int digit = res[i] % 10;
int carry = res[i] / 10;
res[i] = digit;
res[i + 1] += carry;
}
bool null = false;
for (int i = bigLen + smallLen - 1; i >= 0; i--)
{
if (res[i] != 0 && res[i + 1] == 0)
{
null = true;
}
if (null)
{
cout << res[i];
}
}
cout << endl;
}
void printArr(char *c1, char *c2, int len1, int len2)
{
for (int i = 0; i < len1; i++)
{
cout << c1[i];
}
cout << " * ";
for (int i = 0; i < len2; i++)
{
cout << c2[i];
}
cout << " = ";
}
Just initialize your char arrays to empty ones:
char cArr1[500] = {};
char cArr2[500] = {};
then, for the sake of clarity, assign the lengths from your arguments to two integers, casting them since the compiler might warn you about incompatibility between size_t and int.
int lenArg1 = 0;
int lenArg2 = 0;
lenArg1 = (int)strlen ( argv[1] );
lenArg2 = (int)strlen ( argv[2] );
Then, printing the lengths len1 and len2 for debugging purposes only:
int len1 = strlen ( cArr1 );
int len2 = strlen ( cArr2 );
cout << "len1 >> " + to_string(len1) <<endl;
cout << "len2 >> " + to_string(len2) <<endl;
In fact, as #Kevin SUN mentioned, it was possible that your argument reading steps were missing the null characters, however, after running some tests it seems to work fine just by initializing the char arrays.
Also, as mentioned in the comments you need to increase the size reserved for res array, I did it to 500
Compiled with g++ -Wall main.cpp -o calc.exe and running: calc 10 100
Without initialization you get problems like:
after initializing, the output works just fine:

compiling in linux using g++

I have following code which is simply tokenizing an array and then deviding on the basis of '<' and '>' characters. It is running fine in VS community 2019 but when I run it in Linux using g++ command it gives
Free(): invalid pointer
and
Aborted (core dumped)
errors. What am I doing wrong.
PS: error seems to be in the instructions where I am deallocating b in rangbrk and langbrk because when I put it in comments it runs fine in Linux too. But it runs fine in VS 2019 anyways.
//#include <sys/types.h>
//#include <sys/wait.h>
//#include <sys/stat.h>
#include <fcntl.h>
//#include <unistd.h>
#include<string.h>
#include<stdio.h>
#include<fstream>
#include<iostream>
#include<stdlib.h>
using namespace std;
//_________________________________________________________
int reads(char str[])
{//a simple function to get input
int s = 1;
char buffer[100];
cout << "enter command" << endl;
cin.getline(buffer, 100);
if (strlen(buffer) == 0)
{
cout << "Couldnt get input\n";
return 0;
}
for (int i = 0; i <= strlen(buffer); i++)
{
str[i] = buffer[i];
if (buffer[i] == 32)
s++;
}
return s;
}
//____________________________________________________________
int tokenizing(char** a, char str[], char buff[50], int x)
{//a function to devide a complete string into smaller parts
//also stores '/bin/command' into buff to pass as first parameter of execvp
int k = 0, m = 0;
bool check = false;
for (int i = 0; i < x; i++)
{
a[i] = new char[50];
for (int j = 0; str[k] != 32; j++)
{
if (str[k] == 0)
{
check = true;
break;
}
a[i][j] = str[k];
if (i == 0)
buff[j + 5] = str[k];
k++;
a[i][j + 1] = 0;
if (i == 0)
buff[j + 6] = 0;
}
m++;
k++;
if (check)
break;
}
return m;
}
//__________________________________________________________
void rangbrk(char**& a, char**& b, int& x, char filename[])
{//saperates the array before and after '>'
for (int i = 0; i < (x - 2); i++)
{
b[i] = new char[50];
for (int j = 0; j < 50; j++)
{
b[i][j] = a[i][j];
}
}
b[x - 2] = NULL;
for (int i = 0; i < 50; i++)
{
filename[i] = a[x - 1][i];
}
char** c;//temprory pointer to swap a and b
c = a;
a = b;
b = c;
x = x - 2;
for(int i=0;i<x-1;i++)
{
delete [] b[i];
}
b=NULL;
}
//__________________________________________________________
void langbrk(char** &a, char** &b, int& x, int index, char filename[])
{//saperates the array before and after '<'
int k = 0;
for (int i = 0; i < x; i++)
{
if ((i != index) && (i != index - 1))
{
b[k] = new char[50];
for (int j = 0; j < 50; j++)
{
b[k][j] = a[i][j];
}
k++;
}
}
b[x - 2] = NULL;
for (int i = 0; i < 50; i++)
{
filename[i] = a[index - 1][i];
}
char** c;//temprory pointer to swap a and b
c = a;
a = b;
b = c;
x = x - 2;
for(int i=0;i<x-1;i++)
{
if(b[i]!=NULL)
delete [] b[i];
}
b=NULL;
}
//__________________________________________________________
int main()
{
char buff[50] = { "/bin/" };
char str[100];
char exit[5] = { 'e','x','i','t',0 };
char outfile[50];
char infile[50];
int x = reads(str);
char** a;
a = new char* [x];
int s = tokenizing(a, str, buff, x);
a[s] = NULL;
bool flag = false;
for (int i = 0; a[i] != NULL; i++)
cout << a[i] << endl;
cout << s << endl;;
for (int i = 0; i < s; i++)
{
if (a[i][0] == '>')//checks if it need to print in a file
{
cout << i;
char** b;
b = new char* [s - 2];
rangbrk(a, b, s, outfile);
flag = true;
cout << "New" << endl;
for (int j = 0; j < s; j++)
cout << a[j] << endl;
i = 0;
}
else if (a[i][0] == '<')
{
cout << i;
char** c;
c = new char * [s - 2];
langbrk(a, c, s, i, infile);
cout << "New" << endl;
for (int j = 0; j < s; j++)
cout << a[j] << endl;
i = 0;
}
}
}
The reads function gets input, tokenizing tokenized the string in form of words. langbrk copies the string having index 1 less than index of '<' in infile and removes them both from main char** a. rangbrk removes '>' and string succeeding it from a and stores it in outfile

Improve on binary converting algorithm (include negative numbers)

I'm doing some C++ array homework. The goals is to convert decimal to binary (include negative numbers). Here's my code, it gets the job done, but I would like to see if anything can be improved, or any better algorithm (using binary shift maybe?).
#include <iostream>
using namespace std;
// doi tu thap phan sang nhi phan
void decToBinary(int n, int nhiphan[])
{
for (int i=0; i < 16; i++)
{
// to binary
nhiphan[i] = n % 2;
n = n / 2;
}
// inverse array
for (int i = 0, j = 15; i < j; i++, j--)
{
int temp = nhiphan[i];
nhiphan[i] = nhiphan[j];
nhiphan[j] = temp;
}
}
void reverse(int& a)
{
if (a == 0)
a++;
else a--;
}
void outArr(const int a[], int size) {
for (int i = 0; i < size; ++i)
cout << a[i];
}
int main()
{
int nhiphan[16];
int n;
do {
cout << "Nhap so (-255 <= n <= 255) chuyen doi sang nhi phan (16 bit): ";
cin >> n;
} while (n > 255 || n < -255);
if (n < 0) {//check negative
n *= -1;
decToBinary(n, nhiphan);
for (int i = 0; i < 16; i++)// 1's complement
reverse(nhiphan[i]);
// +1
if (nhiphan[15] == 0)//2's complement
nhiphan[15] = 1;
else
{
nhiphan[15] = 0;
int i = 15;
do {
reverse(nhiphan[i-1]);
i--;
} while (nhiphan[i-1] == 0);
}
}
else decToBinary(n, nhiphan);
outArr(nhiphan, 16);
return 0;
}

implantation of RSA algorithm in c++ [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am working on a project to implement RSA algorithm in c++ and i have no idea about c++ before but I'm still learning,
My question in RSA is how to encode characters to numbers from 0-25:
a encode to 0,
b to 1,
c to 2,
.
.
z to 25,
here is my code:
/*
* C++ Program to Implement the RSA Algorithm
*/
#include<iostream>
#include<math.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
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();
int prime(long int pr)
{
int i;
j = sqrt(pr);
for (i = 2; i <= j; i++)
{
if (pr % i == 0)
return 0;
}
return 1;
}
int main()
{
cout << "\nENTER FIRST PRIME NUMBER\n";
cin >> p;
flag = prime(p);
if (flag == 0)
{
cout << "\nWRONG INPUT\n";
exit(1);
}
cout << "\nENTER ANOTHER PRIME NUMBER\n";
cin >> q;
flag = prime(q);
if (flag == 0 || p == q)
{
cout << "\nWRONG INPUT\n";
exit(1);
}
cout << "\nENTER MESSAGE\n";
fflush(stdin);
cin >> msg;
for (i = 0; msg[i] != NULL; i++)
m[i] = msg[i];
n = p * q;
t = (p - 1) * (q - 1);
ce();
cout << "\nPOSSIBLE VALUES OF e AND d ARE\n";
for (i = 0; i < j - 1; i++)
cout << e[i] << "\t" << d[i] << "\n";
encrypt();
decrypt();
return 0;
}
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;
cout << "\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;
cout << "\nTHE DECRYPTED MESSAGE IS\n";
for (i = 0; m[i] != -1; i++)
printf("%c", m[i]);
}
Not sure I get your question right but my bet is you're asking how to convert between ASCII and number representation of characters.
Encoding/Decoding has nothing to do with RSA. You just use dynamic range shift. As the alphabet is in increasing order in ASCII so the only thing left is to offset the a or A to zero.
for lowercase char to number conversion try:
char c='m'; // c is you character m for example
int i=c-`a`; // i is output number
if you got both lowercase and uppercase letters then you need to change it to :
char c='q'; // c is you character q for example
int i; // i is output number
if ((c>='a')&&(c<='z')) i=c-'a';
else i=c-'A';`
where c is your character and i is output number
For number to char conversion try:
c=i+`a`;
or for uppercase:
c=i+`A`;

How do I get this random number generator out of an infinite loop?

I have an assignment for school where I need to create a lottery program. It is supposed to allow the user to input six numbers and then generate six random numbers for comparison. I got the inputs working, but I have encountered a problem where the random number generator (located in the while loop) is stuck in an infinite loop, and I have absolutely no idea what is causing it since I have never had an infinite loop in any previous programs. If someone could please look through the code and possibly establish what is wrong, I would greatly appreciate it.
#include<iostream>
#include<time.h>
using namespace std;
void randomizeSeed();
int randomRange(int min, int max);
int getInteger();
int main()
{
randomizeSeed();
const int minNumber = 1;
const int maxNumber = 49;
const int Size = 6;
int luckyNumbers[6] = {};
int randomNumber = randomRange(minNumber, maxNumber);
int winningNumbers[6] = {};
cout << "Enter six numbers between 1 and 49...\n";
{
for (int i = 0; i < Size; i++)
{
luckyNumbers[i] = getInteger();
}
for (int i = 0; i < Size; i++)
{
for (int i = 0; i < Size - 1; i++)
{
if (luckyNumbers[i] > luckyNumbers[i + 1])
{
int temp = luckyNumbers[i];
luckyNumbers[i] = luckyNumbers[i + 1];
luckyNumbers[i + 1] = temp;
}
}
}
cout << "Lucky Numbers: ";
for (int i = 0; i < Size; i++)
{
cout << luckyNumbers[i] << " ";
}
cout << "\n";
cout << "Press any button to see the Winning Numbers.\n";
system("pause");
bool exist = true;
while (exist == true)
{
int count = 0;
cout << "Winning Numbers: ";
for (int j = 0; j < 6; j++)
{
winningNumbers[j] = randomRange(1, 49);
cout << winningNumbers[j] << " ";
system("pause");
}
}
}
}
void randomizeSeed()
{
srand(time(NULL));
}
int randomRange(int min, int max)
{
int randomValue = rand() % (max + 1 - min) + min;
return randomValue;
}
int getInteger()
{
int value = 0;
while (!(cin >> value) || (value >= 50) || (value <= 0))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
return value;
}
for (int i = 0; i < Size; i++)
for (int i = 0; i < Size - 1; i++)
if (luckyNumbers[i] > luckyNumbers[i + 1])
{
int temp = luckyNumbers[i];
luckyNumbers[i] = luckyNumbers[i + 1];
luckyNumbers[i + 1] = temp;
}
You have two loops and they both use i. You probably mean to use the second loop with another variable name, for example:
for (int i = 0; i < Size; i++)
{
for (int k = 0; k < Size - 1; k++)
{
if (luckyNumbers[i] > luckyNumbers[k + 1])
{
int temp = luckyNumbers[i];
luckyNumbers[i] = luckyNumbers[k + 1];
luckyNumbers[k + 1] = temp;
}
}
}
If you set your compiler warning level to 4 then compiler should warn you about these errors. Try to resolve all compiler warnings.