Randomizing char array to display random password - c++

I have been tasked with create a solution which will generate a secure password for the user.
i need to...
Prompt the user for the length of the password, the number of
special characters along with the number of numbers.
A password should then be generated randomly using those inputs.
for example output:
What’s the password length? 8
How many special characters? 2
How many numbers? 2
Your password is:
aun2$1s#
My level of programming is at a beginner stage here is and example of what i have done so far
#include <iostream>
#include <algorithm>
using namespace std;
void WorkoutPass(int ,int,int);
int passlength;
int specChar;
int number;
int main()
{
cout << "Enter the length of password: ";
cin >> passlength;
if (passlength > 0)
{
cout << "Enter the amount of special characters: ";
cin >> specChar;
if (specChar > passlength)
{
cout << "Error - invalid value entered is above the length of password";
}
cout << "Enter amount of numbers";
cin >> number;
if (number > passlength)
{
cout << "Error - invalid value entered is above the length of password";
}
WorkoutPass(passlength, specChar, number);
}
else
{
cout << "Error - invalid value entered password must be above zero";
}
return 0;
}
void WorkoutPass(int p, int s, int n)
{
string password;
char alphaBetArray[26] = {'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'};
char specCharArray[10] = {'!','£','$','%','&','#','~','#','>','<'};
char numberArray[10] = {'1','2','3','4','5','6','7','8','9','10'};
int numberOfLetters = p - s - n;
char letter;
// generate (numberOfLetters) letters
// each letter generated we add to the string
password += letter;
// Add special characters
// Add numbers
random_shuffle(password.begin(), password.end());
cout << password.c_str() << endl;
}
void DisplayPass()
{
}

c++17 has introduced sample Which you'll want to use along with the random_shuffle you already have in place to generate password:
random_device rd;
mt19937 g(rd());
auto it = sample(cbegin(alphaBetArray), cend(alphaBetArray), begin(password), numberOfLetters, g);
it = sample(cbegin(specCharArray), cend(specCharArray), it, s, g);
sample(cbegin(numberArray), cend(numberArray), it, n, g);
Live Example
A couple notes:
Your arrays are not comprehensive, writing a lambda to randomly generate characters in a range may be a preferable option, you could do that using generate_n.
random_shuffle was deprecated in c++14 you need to use shuffle now

You "just" miss the random generation part, which you can get through the rand function.
So in your case that will be:
for (int i=0; i<numberOfLetters; i++)
password += alphaBetArray[rand()%sizeof(alphaBetArray)];
for (int i=0; i<s; i++)
password += specCharArray[rand()%sizeof(specCharArray)];
for (int i=0; i<n; i++)
password += numberArray[rand()%sizeof(numberArray)];
Be sure to check in the input also the sum of special chars and numbers, now you just check the single entries but someone could put: 10 (password length), 6 (special chars), 7 (numbers), and that's bad.

Generate p random chars
Generate s special chars
Generate n random numbers
Concatenate them and shuffle them
string workout_pass(int p, int s, int n)
{
string password;
const char alphaBetArray[26] = {'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'};
const char specCharArray[10] = {'!','£','$','%','&','#','~','#','>','<'};
const char numberArray[10] = {'1','2','3','4','5','6','7','8','9','10'};
int numberOfLetters = p - s - n;
for (i = 0 ; i < numberOfLetters; ++i ) {
password += alphaBetArray[rand() % 26];
}
for (i = 0 ; i < s; ++i ) {
password += specCharArray[rand() % 10];
}
for (i = 0 ; i < n; ++i ) {
password += numberArray[rand() % 10];
}
random_shuffle(password.begin(), password.end());
return password;
}
Some comments :
Since it is a function it is better not to use CamelCase
Since it is a function you better return the generated string and not void
Try to get rid of the char arrays and play with ascii numbers (like 97 + (rand() % 26)) for [a-z]
Last but not least better use C with these problems not C++/STL functions like random_shuffle and try to achieve the same result, you will learn best that way

Related

Convert number in binary and print out as matrix (C++)

Before you read ahead or try to help, this question is regarding my homework so the requirements to this question will be very specific.
I am writing a code that takes a user input between 0 and 511 and converts it into a binary number. Then the program will replace all the 1's in the binary number with T and all the 0's in the number as H. Afterwards it will print out the results (the binary number with the H and T replacement) as a 3*3 matrix.
This is the desired output (not what I have but what I want):
Enter a number between 0 and 511: 299
The binary number is: 100101011
The matrix is:
THH
THT
HTT
The problem with my code is that I am unsure of how to replace an array that consists of all integers to have certain parts of the index to be either characters or strings. For sure the part with the binary number conversion works but the replacement of the 0's and 1's of the array is where the trouble is at. I am also unsure of how to print out the matrix result. I assume it goes either of 2 ways: 1. The program creates a new array for the previous array's elements stored and prints out the matrix array instead. 2. There is a way to only print the array 3 lines at a time. The only way I can think of is to somehow cut the for loop short and add a line break after every 3 values. I am aware that there are a few pointable errors in my code but I do not know how to fix them.
Although this is in the C++ language, what I have learned is the C style syntax (no std:: kinds of code or stuff like that because I haven't learned it yet and I will not understand it) So far I have learned basic arrays, loops, and functions.
#include <iostream>
using namespace std;
int main(){
int arr[10];
int input, i;
cout<<"Enter a number between 0 and 511: ";
cin>> input;
for(i = 0; input > 0; i++){
arr[i] = (input % 2);
input = input / 2;
}
cout<<"The binary number is: ";
for(i = i - 1; i >= 0; i--){
cout<<arr[i];
}
string newArr[10] = arr[10]; //the error here states that the array initializer must be an initializer list
for(int i = 0; i < sizeof(arr)/sizeof(arr[10]); i++){
if(arr[i] == 1){
arr[i] = "T"; //the error here mentions that a string/ character cannot be assigned with a integer array
}
else{
arr[i] = "H";
}
}
for(int i = 0; i < sizeof(arr)/sizeof(arr[10]); i++){
cout<<arr[i]<< " ";
}
}
This would be sufficient:
#include <iostream>
using namespace std;
int main()
{
// you never actually checked if the input is valid
// so you may or may not want this loop:
int input;
do
{
cout << "Enter a number between 0 and 511: ";
cin >> input;
} while ((input < 0) || (input > 511));
// space for matrix, new lines and null
// to construct a null terminated string
char buffer[3 * (3 + 1) + 1];
int i = 0;
// since the bits are read from left to right
// I will use a mask instead of bit shifting the input
int bit = 1 << 9;// 2^9 == 512
for (int r = 0; r < 3; r++)// rows
{
for (int c = 0; c < 3; c++)// columns
{
// this could come after the check
// and then bit would start at 256
bit >>= 1;
// perform the check and add the corresponding letter
buffer[i++] = (bit & input) ? 'T' : 'H';
}
// add new lines
buffer[i++] = '\n';
}
// if you don't want the last '\n'
// this could be { buffer[--i] = '\0'; }
buffer[i++] = '\0';
cout << buffer;
}

Unıque Random Number Check form Array c++

#include <iostream>
#include<ctime>
#include<cstdlib>
#include<string>
#include<cmath>
using namespace std;
int main()
{
bool cont = false;
string str;
int num, num2;
cin >> str >> num;
int arr[10];
int a = pow(10, num);
int b = pow(10, (num - 1));
srand(static_cast<int>(time(NULL)));
do {
num2 = rand() % (a - b) + b;
int r;
int i = 0;
int cpy = num2;
while (cpy != 0) {
r = cpy % 10;
arr[i] = r;
i++;
cpy = cpy / 10;
}
for (int m = 0; m < num; m++)
{
for (int j = 0; j < m; j++) {
if (m != j) {
if (arr[m] == arr[j]) {
break;
}
else {
cont = true;
}
}
}
}
cout << num2 << endl;
} while (!cont);
return 0;
}
I want to take a number from the user and produce such a random number.
For example, if the user entered 8, an 8-digit random number.This number must be unique, so each number must be different from each other,for example:
user enter 5
random number=11225(invalid so take new number)
random number =12345(valid so output)
To do this, I divided the number into its digits and threw it into the array and checked whether it was unique. The Program takes random numbers from the user and throws them into the array.It's all right until this part.But my function to check if this number is unique using the for loop does not work.
Because you need your digits to be unique, it's easier to guarantee the uniqueness up front and then mix it around. The problem-solving principle at play here is to start where you are the most constrained. For you, it's repeating digits, so we ensure that will never happen. It's a lot easier than verifying if we did or not.
This code example will print the unique number to the screen. If you need to actually store it in an int, then there's extra work to be done.
#include <algorithm>
#include <iostream>
#include <numeric>
#include <random>
#include <vector>
int main() {
std::vector<int> digits(10);
std::iota(digits.begin(), digits.end(), 0);
std::shuffle(digits.begin(), digits.end(), std::mt19937(std::random_device{}()));
int x;
std::cout << "Number: ";
std::cin >> x;
for (auto it = digits.begin(); it != digits.begin() + x; ++it) {
std::cout << *it;
}
std::cout << '\n';
}
A few sample runs:
Number: 7
6253079
Number: 3
893
Number: 6
170352
The vector digits holds the digits 0-9, each only appearing once. I then shuffle them around. And based on the number that's input by the user, I then print the first x single digits.
The one downside to this code is that it's possible for 0 to be the first digit, and that may or may not fit in with your rules. If it doesn't, you'd be restricted to a 9-digit number, and the starting value in std::iota would be 1.
First I'm going to recommend you make better choices in naming your variables. You do this:
bool cont = false;
string str;
int num, num2;
cin >> str >> num;
What are num and num2? Give them better names. Why are you cin >> str? I can't even see how you're using it later. But I presume that num is the number of digits you want.
It's also not at all clear what you're using a and b for. Now, I presume this next bit of code is an attempt to create a number. If you're going to blindly try and then when done, see if it's okay, why are you making this so complicated. Instead of this:
num2 = rand() % (a - b) + b;
int r;
int i = 0;
int cpy = num2;
while (cpy != 0) {
r = cpy % 10;
arr[i] = r;
i++;
cpy = cpy / 10;
}
You can do this:
for(int index = 0; index < numberOfDesiredDigits; ++index) {
arr[index] = rand() % 10;
}
I'm not sure why you went for so much more complicated.
I think this is your code where you validate:
// So you iterate the entire array
for (int m = 0; m < num; m++)
{
// And then you check all the values less than the current spot.
for (int j = 0; j < m; j++) {
// This if not needed as j is always less than m.
if (m != j) {
// This if-else is flawed
if (arr[m] == arr[j]) {
break;
}
else {
cont = true;
}
}
}
}
You're trying to make sure you have no duplicates. You're setting cont == true if the first and second digit are different, and you're breaking as soon as you find a dup. I think you need to rethink that.
bool areAllUnique = true;
for (int m = 1; allAreUnique && m < num; m++) {
for (int j = 0; allAreUnique && j < m; ++j) {
allAreUnique = arr[m] != arr[j];
}
}
As soon as we encounter a duplicate, allAreUnique becomes false and we break out of both for-loops.
Then you can check it.
Note that I also start the first loop at 1 instead of 0. There's no reason to start the outer loop at 0, because then the inner loop becomes a no-op.
A better way is to keep a set of valid digits -- initialized with 1 to 10. Then grab a random number within the size of the set and grabbing the n'th digit from the set and remove it from the set. You'll get a valid result the first time.

How to know if a number is a palindrome without using maths?

So I'm thinking if I could use strings to check if a number is a palindrome, but I don't really know how strings, arrays and that stuff works and I'm not arriving at anything.
I've done this using math, but I wonder if it would be easier to use arrays or strings.
n = num;
while (num > 0)
{
dig = num % 10;
rev = rev * 10 + dig;
num = num / 10;
}
// If (n == rev) the number is a palindrome
this is the code made with math
So it works yeah, but I'm curious
It is much easier if you use correctly the index of the array in the loop:
// Num is the number to check
// Supposing we are using namespace std
string numString = to_string(num);
bool palindrome = true;
int index = 0;
while(index < numString.size() && palindrome){
palindrome = numString[index] == numString[numString.size() - index - 1];
index++;
}
if(palindrome)
cout << num << " is a palindrome \n"; // line break included
else
cout << num << " is not a palindrome \n"; // line break included
Use this code:-
//num is the Number to check
//Converting int to String
ostringstream ss;
ss<<num;
string snum = ss.str();
string fromfront="", fromback="";
fromfront = snum;
string character;
for(int i=snum.length();i>0;i--)
{
if(i>0)
character = snum.substr(i-1, 1);
fromback+=character;
}
if(fromfront==fromback)
cout<<endl<<"It is a palindrome.";
else
cout<<endl<<"It is not a palindrome.";

How do I get alphabet from the user

I have a trouble with this. I writing a code for the "vigenere cipher".
I have text and key. But i want to get alphabet from the user. what the user wants etc:"abcdfgh" or "sdgfjdgkfdsgs" just what the user wants.
So but i can't do it.
How do I get alphabet from the user?
Firstly, i want to do get alphabet from the user.
After, I want it to enter the word and encrypt it. But the words alphabet is user's alphabet.
Here is the codes:
#include <iostream>
#include <string>
using namespace std;
// Bu fonksiyon bir key oluşturur.
string generateKey(string str, string key)
{
int x = str.size();
for (int i = 0; ; i++)
{
if (x == i)
i = 0;
if (key.size() == str.size()) // eğer oluşturulan key boyutu girilen
metnin boyutuna eşitse fonksiyonu durdur.
break;
key.push_back(key[i]);
}
return key;
}
string cipherText(string str, string key) // "/Bu fonksiyon orjinal metni şifreler \"
{
string cipher_text;
for (int i = 0; i < str.size(); i++)
{
// converting in range 0-25
int x = (str[i] + key[i]) % 26;
// alfabeyi ASCII kodlarina dönüştür:
x += 'A';
cipher_text.push_back(x);
}
return cipher_text;
}
// "/Bu fonksiyon şifreli metni orjinal hale getirir\"
string originalText(string cipher_text, string key)
{
string orig_text;
for (int i = 0; i < cipher_text.size(); i++)
{
// converting in range 0-25
int x = (cipher_text[i] - key[i] + 26) % 26;
// convert into alphabets(ASCII)
x += 'A';
orig_text.push_back(x);
}
return orig_text;
}
int main()
{
cout << " Sifrelenmesini istediginiz kelimeyi/cumleyi giriniz" << endl;
string str;
getline(cin, str);
//string str = "METINBUGRA";
cout << "Anahtar kelimeyi giriniz." << endl;
string keyword;
getline(cin, keyword);
//string keyword = "ABC";
string key = generateKey(str, keyword);
string cipher_text = cipherText(str, key);
cout << "Sifrelenmis Kelime : "
<< cipher_text << "\n";
cout << "Cozumlenmis kelime : "
<< originalText(cipher_text, key);
system("pause");
return 0;
}
If I correctly understood your question, you want to use a custom alphabet instead of English alphabet. For instance you may add digits.
Instead of actual letters you must operate on numbers: 0, 1, 2, ... N-1, where N is the size of the alphabet. For English alphabet this means you must use 0 instead of A (0x41), 1 instead of B (0x42), ... 25 instead of Z.
If the size of the key is M, the encryption algorithm for letter at position i is:
( L[i] + K[i mod M] ) mod N
Once you have a functional algorithm that operates on numbers, all you have to do is map your input from letters to numbers and your output from numbers to letters.
Mapping numbers to letters is easy; you just have to store the alphabet into a string – this answers your question:
string n_to_letter; // alphabet
//...
int main()
{
//...
cin >> n_to_letter; // read the alphabet
//...
Mapping letters to numbers is probably beyond your current knowledge; you must use a map:
#include <map>
//...
string n_to_letter; // alphabet
map< char, int > letter_to_n;
void init_letter_to_n() //...
If you do not know how to use a map, there is a workaround: just search for the letter in the alphabet string, or use a 256 characters vector/string.
DEMO

Reverse of a number with leading zeroes

How do we reverse a number with leading zeroes in number ?
For ex: If input is 004,
output should be 400.
I wrote below program but it works only when no leading zeroes in input.
int num;
cout<<"Enter number "<<endl;
cin>>num;
int rev = 0;
int reminder;
while(num != 0)
{
reminder = num % 10;
rev = rev * 10 + reminder;
num = num / 10;
}
cout<<"Reverse = "<<rev<<endl;
Is there any way to input a number with leading zeroes ? Even then, Above logic doesn't work for such numbers.
Any simple solution ? It is doable by taking input as string and processing it. But that doesn't look nice.
*EDIT: If length of number is known, it looks to be possible to reverse a number with leading zeroes. (Without using string)*
I shall post the code as soon as it works.
EDIT 2: I tried to put back characters to cin stream and then read and calculate the reverse. It is working for 2 digit numbers.
But if length is known, its far easier to find reverse. All i need to do is, multiply by 10 for required number of times.
So i think, i would go with string approach.
Hoping that interviewer would be happy :)
Leading zeroes are not represented by binary numbers (int, double, etc.) So you'll probably have to use std::string. Read the input into the string, then call std::reverse() passing the string as input.
Yes, you must use a string. You cannot store leading zeros in an int.
If you know the total width you'd like the number to be before-hand, you can reuse the code you have and store the results (from right to left) in a zero initialized array. Note: you'd probably want to add some error checking to the code listed below.
int num, width;
cout<<"Enter number "<<endl;
cin>>num;
cout<<"Enter width: "<<endl;
cin>>width;
int rev[width];
for (int i = 0; i < width; ++i)
rev[i] = 0;
int cnt = width - 1;
int rev = 0;
int reminder;
while(num != 0)
{
reminder = num % 10;
// rev = rev * 10 + reminder;
rev[cnt] = remainder;
--cnt;
num = num / 10;
}
cout << "Reverse: ";
for (int i = 0; i < width; ++i)
cout << rev[i];
cout << endl;
This will allow you to manipulate the number more easily in the future as well.
Read the number in string format (that is, use std::string) and reverse the string.
Once you convert your input to an integer, which you do in line 3, any information about the leading zeroes in the input of the user is lost.
You'll have to use a string.
A recursive approach, but easily converted to a loop...
#include <iostream>
int f(int value = 1)
{
char c;
return (std::cin.get(c) && isdigit(c))
? (c - '0') * value + f(10 * value)
: 0;
}
int main()
{
std::cout << f() << '\n';
}
As ChrisF said, you need to load a string, because 4 and 004 is the same int and you cannot distinguish it after you assign it to an int variable.
The next thing to do is trim the string to contain just digits (if you want to be correct) and run std::reverse on it - and you're done.
Keep the number as a string, and use std::reverse.
std::string num;
std::cout << "Enter number " << std::endl;
std::cin >> num;
std::string rev(num);
std::reverse(rev.begin(), rev.end());
std::cout << "Reverse = " << rev << std::endl;
Replace your while loop with a for loop with the same number of runs as you wish the original number has digits (including leading zeros). e.g. 004 would require the loop to be run 3 times, and not to terminate prematurely once x == 0.
s = int(raw_input(" enter the no of tyms :"))
n = 0
list, list1 = [], []
while n <= s:
m = raw_input("enter the number:")
n=n+1
list.append(m)
print list
list.reverse()
print list
Reverse in one of the best lang Python.