C# pass gen recursion - c#

I have a password generator that uses the ascii table. I am trying to learn how to use the recursion with it. I know there are easy ways to make a generator but I want to learn more about recursion. I want it to choose the letters (65-90) but also choose the numbers (000 - 009)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class PasswordGenerator
{
static void Main()
{
bool bypass = false;
string errorMessage = "That is an Invalid Number, Please try again";
string howManyCharacters = "How many Characters would you like the Password to be? (Press '0' to Stop)";
string pressKeyMessage = "Press any key to continue";
int length = 0;
do
{
var passwordBuilder = new StringBuilder();
Console.WriteLine(howManyCharacters);
var inputIsNumber = int.TryParse(Console.ReadLine(), out length);
if (!inputIsNumber)
{
Console.WriteLine(errorMessage);
bypass = false;
}
else if (inputIsNumber && length != 0)
{
for (int i = 0; i < length; i++)
passwordBuilder.Append(GetRandomChar());
Console.WriteLine();
Console.WriteLine("Password: " + passwordBuilder.ToString());
Console.WriteLine();
}
else
{
Console.WriteLine();
Console.WriteLine(pressKeyMessage);
Console.ReadLine();
bypass = true;
}
}
while (!bypass);
}
static Random _r = new Random();
static char GetRandomChar()
{
return (char)_r.Next(65, 90); // A through Z
}
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
class PasswordGenerator
{
static void Main()
{
bool bypass = false;
int length = 0;
do
{
var passwordBuilder = new StringBuilder();
Console.WriteLine("How many Characters would you like the Password to be? (Press '-1' to Stop)");
/// try method is inside, replaced old try and catch
var Input_is_Int = int.TryParse(Console.ReadLine(), out length);
if (!Input_is_Int || length == 0)
{
Console.WriteLine("That is an Invalid Number, Please try again");
Console.WriteLine();
bypass = false;
}
else if (Input_is_Int && length != -1)
{
for (int i = 0; i < length; i++)
passwordBuilder.Append(GetRandomChar());
Console.WriteLine("Password: " + passwordBuilder.ToString());
Console.WriteLine();
}
else
{
Console.WriteLine();
Console.WriteLine("Press any key to continue");
Console.ReadLine();
bypass = true;
}
}
while (!bypass);
}
/// Union of ABCDEFGHIJKLMNOPQRSTUVWXYZ, 0123456789 and !"#$%&'()*+,-./
static char[] _lookupTable = Enumerable.Range(65, 26).Union(Enumerable.Range(48, 10).Union(Enumerable.Range(33, 14))).Select(i => (char)i).ToArray();
static Random _r = new Random();
static char GetRandomChar()
{
var index = _r.Next(0, _lookupTable.Length);
return _lookupTable[index];
}
}

Related

System.FormatException: input string was not in correct Format [duplicate]

This question already has an answer here:
first Console.ReadLine() returns immediately
(1 answer)
Closed 2 years ago.
Here's the code:
using System;
using manjan_in_csharp.Classes;
namespace manjan_in_csharp
{
class Program
{
static void Main()
{
Console.WriteLine("What Do You Want ? \nPress");
Console.WriteLine("'s' to use sort");
var wish =(char)Console.Read(); //explicitly converting to char (char)
// Console.WriteLine(wish.GetType());
switch (wish)
{
case 's':
Console.WriteLine("Enter the size of unsort list");
Sort sort = new Sort();
var size = int.Parse(Console.ReadLine());
sort.CallingSort(size);
break;
default:
Console.WriteLine("Invalid Operation");
break;
}
}
}
}
Now, I only enter s when the line appears "Press s to use sort" and I get this error:
I have no idea what's causing the problem. I mean, I enter s and then it doesn't let me do anything and the program crashes and I get that error.
Btw, here's the Sort class
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading;
namespace manjan_in_csharp.Classes
{
public class Sort
{
public void CallingSort(int size)
{
var datetimenow = DateTime.Now;
Console.WriteLine("|| Sorting Progra ||\t\t\t DATE/TIME: " + datetimenow.ToString("dd-mm-yyyy hh-mm"));
Console.WriteLine("Now Which Sort Method you want to apply");
Console.WriteLine("'b' for BubbleSort");
var method = (char)Console.Read();
switch (method)
{
case 'b':
Bubblesort(ListInitilizer(size));
break;
default:
Console.WriteLine("There is no sort related to that");
break;
}
}
public List<int> ListInitilizer(int size)
{
List<int> unsortlist = new List<int>();
Random random = new Random();
for (int i = 0; i < size; i++)
{
unsortlist.Insert(i, random.Next(0, size));
}
Console.WriteLine("Now the unsort list is :");
for (int i = 0; i < size; i++)
{
Console.Write(unsortlist[i] + " ");
}
Console.WriteLine();
return unsortlist;
}
public void Bubblesort(List<int> unsortlist)
{
var start = DateTime.Now;
for (int i = 0; i < unsortlist.Count; i++)
{
for (int j = i; j < unsortlist.Count; j++)
{
if (unsortlist[j] < unsortlist[i])
{
int temp = unsortlist[i];
unsortlist[i] = unsortlist[j];
unsortlist[j] = temp;
}
}
}
Console.WriteLine("Applying Bubblesort");
Console.WriteLine("Items in Sorted List : "+unsortlist.Count);
for (int i = 0; i < unsortlist.Count; i++)
{
Console.Write(unsortlist[i] + " ");
}
var end = DateTime.Now;
Console.WriteLine("\nTotal Duration is : " + (end - start) + " Seconds");
}
}
}
The problem is with the combination of these two lines of code:
var wish =(char)Console.Read();
...
var size = int.Parse(Console.ReadLine());
The Console.Read() takes only single character from the input stream so for your input 's' followed by carriage-return. The carriage-return is discarded which will then be passed to next read i.e. Console.ReadLine().
You can either use ReadLine() for the first input as well or use ReadKey(). Modify your Main() as such
static void Main()
{
Console.WriteLine("What Do You Want ? \nPress");
Console.WriteLine("'s' to use sort");
var wish = Console.ReadKey().Key; //explicitly converting to char (char)
// Console.WriteLine(wish.GetType());
switch (wish)
{
case ConsoleKey.S:
Console.WriteLine("Enter the size of unsort list");
Sort sort = new Sort();
var size = int.Parse(Console.ReadLine());
sort.CallingSort(size);
break;
default:
Console.WriteLine("Invalid Operation");
break;
}
}

How can i get index of two same character in string?

I want to create simple console wingman game.My error is that if i try get pos of 2 same character in word i get only one and the other is skipped.
For example Tomatoe.
Console output:
Tomatoe
_ o m a t _ _
I know i didnt use live didnt have time for that i do it layter.
class Program {
static string[] word = { "Pineapple", "Apple" , "Tomatoe" , "Pizza"};
static int wordIndex = 0;
static char[] randomWord;
static bool guessing = true;
public static void Main(string[] args)
{
int lives = 3;
Console.OutputEncoding = Encoding.UTF8;
Console.InputEncoding = Encoding.UTF8;
Random r = new Random();
wordIndex = r.Next(word.Length);
randomWord = word[wordIndex].ToLower().ToCharArray();
char[] randomWordcensored = new char[randomWord.Length];
for (int i = 0; i < randomWord.Length; i++)
{
randomWordcensored[i] = '_';
}
Console.WriteLine("Hello");
foreach (var item in randomWordcensored)
{
Console.Write(item + " ");
}
Console.WriteLine();
Console.WriteLine("Please Enter character:");
while (guessing = true)
{
int g = 0;
char userinput;
bool security = char.TryParse(Console.ReadLine() ,out userinput);
if (security == true) {
if (randomWord.Contains(userinput))
{ //help needed
g = (word[wordIndex].ToString().IndexOf(userinput) == -1 ? 0 : word[wordIndex].ToString().IndexOf(userinput));
randomWordcensored[g] = userinput;
Console.WriteLine("Good :) " + g);
foreach (var item in randomWordcensored)
{
Console.Write(item + " ");
}
}
else
{
lives--;
Console.WriteLine("Wrong!\n-Lives:" + lives);
}
}
else
{
Console.WriteLine("Enter only one charracter!");
}
}
}
}
You'll want to handle user input that might be different casing and such. Because of that it's easiest to just visit every character in the random word just once.
Here's a REPL that I made to solve this:
using System;
using System.Collections.Generic;
class MainClass {
public static void Main (string[] args) {
var word = "Tomato";
var input = "t";
var letter = input.ToLower()[0];
var indices = new List<int>();
for(var i = 0; i < word.Length; i++)
if (word.ToLower()[i] == letter)
indices.Add(i);
Console.WriteLine($"Secret word: {word}");
Console.WriteLine($"User guess: {input}");
Console.WriteLine($"Found at {String.Join(", ", indices)}");
}
}
and its output:
Mono C# compiler version 4.0.4.0
Secret word: Tomato
User guess: t
Found at 0, 4

Can't get my method to upper case my string arrays

The whole program is listed after, but the only problem i have with it is the ToUppers() method. I just want this method to iterate over each string in my array, and then make everything upper case.
private static string[] ToUppers(string[] stringToUpperArrays)
{
string stringer;
foreach (string value in stringToUpperArrays)
{
stringer = value.ToUpper(); // <== this line highlighted
Console.WriteLine(stringer);
}
return stringToUpperArrays;
}
The program executes after it prints it on the console, and it lists a NullReferenceException, and highlights the stringer = value.ToUpper(); line
The whole program
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Utility;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//Mark Bouwman
//CNT A01
//ICA18
//April 2nd
string answer;
int numInArray;
string[] stringArrays;
string[] stringArraysToDisplay;
string[] stringToUpperArrays;
//TITLE
Console.WriteLine("\t\tStringy");
do
{
numInArray = Utility.Utility.GetInt(2, 10, "Enter the size of the array from 2 to 10: ");
stringArrays = CreateArray(numInArray);
stringArraysToDisplay = Display(stringArrays);
stringToUpperArrays = ToUppers(stringArrays);
//aksing to run program again
Console.Write("Run program again? yes or no: ");
answer = Console.ReadLine();
}
while (answer.Equals("yes", StringComparison.CurrentCultureIgnoreCase));
}
private static string[] CreateArray(int numInArray)
{
int index;
string[] stringArray;
stringArray = new string[(numInArray + 1)];
for (index = 0; index < numInArray; ++index)
{
Console.Write("Enter string #" + (index + 1) + " ");
stringArray[index] = Console.ReadLine();
}
return stringArray;
}
private static string[] Display(string[] stringArraysDisplay)
{
foreach (string value in stringArraysDisplay)
{
Console.WriteLine(value);
}
return stringArraysDisplay;
}
private static string[] ToUppers(string[] stringToUpperArrays)
{
string stringer;
foreach (string value in stringToUpperArrays)
{
stringer = value.ToUpper();
Console.WriteLine(stringer);
}
return stringToUpperArrays;
}
}
}
In CreateArray you define the array to size of numInArray + 1 but you fill the array only with numInArray strings, i.e. the last index is empty. When you try value.ToUpper(); on the empty index you get the exception.
In CreateArray change
stringArray = new string[(numInArray + 1)];
To
stringArray = new string[numInArray];
Or change
for (index = 0; index < numInArray; ++index)
{
Console.Write("Enter string #" + (index + 1) + " ");
stringArray[index] = Console.ReadLine();
}
To
for (index = 0; index < stringArray.Length; ++index)
{
Console.Write("Enter string #" + (index + 1) + " ");
stringArray[index] = Console.ReadLine();
}
You should erase the + 1 when you are initializing the array
stringArray = new string[(numInArray)];
in this method
private static string[] CreateArray(int numInArray)

How to assign a value read from the console to an integer field?

In my hangman game, I am attempting to prompt the user to enter the number of "lives" (or guesses) the player should be given. After I type a number at the prompt, the following error message is displayed:
Cannot implicitly convert type 'int' to 'string'
The following line causes the error:
lives = Console.ReadLine();
The lives field is an integer. How can I correctly assign a user-entered value to an integer field?
Here is my complete code:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
namespace ConsoleApplication6
{
class Hangman
{
//guesses
public static int lives = 5;
//Words for the game
static string[] wordBank = { "study", "cat", "dress", "shoes", "lipstick" };
// Create new ArrayList and initialize with words from array wordBank
static ArrayList wordList = new ArrayList(wordBank);
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.Title = "C# Hangman";
Console.WriteLine("Hang man!");
//Gamemenu
string response = "";
do
{
Console.Write("Enter Command (1. Add Words, 2. List Words , 3. Play , 4. Exit) Pick 1-4: ");
response = Console.ReadLine();
switch (response)
{
case "1": AddWord(); break;
case "2": ListWords(); break;
case "3": Play(); break;
case "4": break;
}
} while (response != "4");
}
//add words to list
static void AddWord()
{
Console.Write("Enter the word to add: ");
String temp = Console.ReadLine();
wordList.Add(temp);
Console.WriteLine("{0} was added to the dictionary!", temp);
}
//Display words
static void ListWords()
{
foreach (Object obj in wordList)
Console.WriteLine("{0}", obj);
Console.WriteLine();
}
//How many guesses
static void AskLives()
{
try
{
Console.WriteLine("please enter number of lives?");
//This line gives me the error
lives = Console.ReadLine();
}
catch
{
// if user does not enter a number ask it again
AskLives();
}
}
//Gameplay
static void Play()
{
Random random = new Random((int)DateTime.Now.Ticks);
string wordToGuess = wordList[random.Next(0, wordList.Count)].ToString();
string wordToGuessUppercase = wordToGuess.ToUpper();
StringBuilder displayToPlayer = new StringBuilder(wordToGuess.Length);
for (int i = 0; i < wordToGuess.Length; i++)
displayToPlayer.Append('-');
List<char> correctGuesses = new List<char>();
List<char> incorrectGuesses = new List<char>();
bool won = false;
int lettersRevealed = 0;
string input;
char guess;
AskLives();
while (!won && lives > 0)
{
Console.WriteLine("Current word: " + displayToPlayer);
Console.Write("Guess a letter: ");
input = Console.ReadLine().ToUpper();
guess = input[0];
if (correctGuesses.Contains(guess))
{
Console.WriteLine("You've already tried '{0}', and it was correct!", guess);
continue;
}
else if (incorrectGuesses.Contains(guess))
{
Console.WriteLine("You've already tried '{0}', and it was wrong!", guess);
continue;
}
if (wordToGuessUppercase.Contains(guess))
{
correctGuesses.Add(guess);
for (int i = 0; i < wordToGuess.Length; i++)
{
if (wordToGuessUppercase[i] == guess)
{
displayToPlayer[i] = wordToGuess[i];
lettersRevealed++;
}
}
if (lettersRevealed == wordToGuess.Length)
won = true;
}
else
{
incorrectGuesses.Add(guess);
Console.WriteLine("Nope, there's no '{0}' in it!", guess);
lives--;
}
Console.WriteLine(displayToPlayer.ToString());
}
if (won)
Console.WriteLine("You won!");
else
Console.WriteLine("You lost! It was '{0}'", wordToGuess);
Console.Write("Press ENTER to exit...");
Console.ReadLine();
}
}
}
Your lives field is an integer, but Console.ReadLine returns a string.
You can use Int32.Parse(Console.ReadLine()) to parse the input into an integer. Note that an exception will be thrown if the text entered by the user cannot be interpreted as an integer.
Your catch block will work here and re-prompt. It would be more appropriate to use the Int32.TryParse method:
int tmpLives;
if (Int32.TryParse(Console.ReadLine(), out tmpLives))
{
lives = tmpLives;
}
else
{
AskLives();
}
You want to do something along the lines of:
string livesString = Console.ReadLine();
lives = Convert.ToInt32(livesString);
I'm guessing Console.ReadLine() gives you a string. This will not play ball with your integer lives. You could try this:
lives = Int.Parse(Console.ReadLine())

Generate password using a for loop

I am making a password generator that generates a random number, then I have it converted to a letter using ascii. Inside the for loop, I need the letters to convert a string instead of a list. It works, but it just displays random letters as a list.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
class MainClass
{
static void Main()
{
int x = 1;
int length;
string a = "Press any key to continue";
object num;
while (x == 1)
{
Console.WriteLine("How many Characters would you like the Password to be? (Press -1 to Stop)");
length = Convert.ToInt32(Console.ReadLine());
try
{
for (int i = 0; i < length; i++)
{
int num1 = Number();
Int32 ASCII = num1;
num = (char)num1;
if (length > 0)
{
Console.WriteLine(num);
}
}
}
catch
{
Console.WriteLine(a);
}
if (length == -1)
break;
}
}
static Random _r = new Random();
static int Number()
{
return _r.Next(65, 90); // decimal
}
}
StringBuilder sb = new StringBuilder();
for( int i = 0; i < length; i++ )
{
int num1 = Number();
Int32 ASCII = num1;
num = (char)num1;
sb.Append( num );
}
Console.WriteLine( sb.ToString() );
This isn't how I would build a password nor how I would generate random text, but this will give you a string and answer the original question.
As to how I would do this task:
System.Security.Cryptography.RNGCryptoServiceProvider _crypto = new System.Security.Cryptography.RNGCryptoServiceProvider();
byte[] bytes = new byte[8]; // this array can be larger if desired
_crypto.GetBytes( bytes );
ulong randomNumber = (ulong)BitConverter.ToInt64( bytes, 0 );
// convert to a string with the encoding of your choice; I prefer Base 62
For completeness sake, here's a Base62 algorithm which I use. Base62 has the advantage over the more commonly-used Base64 in that it does not include any special characters so it is easy to use in query strings, HTML, and JavaScript (with a few minor caveats). Of course, passwords shouldn't be used in any of those places, and you may want to include special characters to make a password more complex.
Regardless, here is how I convert random numbers to Base62.
private static readonly char[] _base62Characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
public static string ToBase62String( long value )
{
if( value < 0L )
{
throw new ArgumentException( "Number must be zero or greater." );
}
if( value == 0 )
{
return "0";
}
string retVal = "";
while( value > 0 )
{
retVal = _base62Characters[value % 62] + retVal;
value = value / 62;
}
return retVal;
}
Lastly, I want to point out that passwords should very rarely be generated for any purpose, because that means they are being distributed in some form. Passwords should be hashed and salted; password resets should rely on random, expiring security tokens allowing the user a one-time reset. Passwords should never be emailed to a user; passwords should never be stored in plaintext or any reversible format.
For password reset token generation, the code I provided could work nicely because it produces a large, cryptographically random number encoded with a web-safe format. But even a hashed GUID would do the trick in that case.
var sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.Append((char)Number());
}
string password = sb.ToString();
Console.WriteLine(password );
But I would change your Number() method to:
private static char GetRandomChar()
{
return (char)_r.Next(65, 90);
}
and then replace the line inside the loop:
sb.Append(GetRandomChar());
//You have to append the values generated by the RandomNumber in to your password variable
class MainClass
{
static void Main()
{
int x = 1;
int length;
string a = "Press any key to continue";
string num=string.Empty;
while (x == 1)
{
Console.WriteLine("How many Characters would you like the Password to be? (Press -1 to Stop)");
length = Convert.ToInt32(Console.ReadLine());
try
{
for (int i = 0; i < length; i++)
{
int num1 = Number();
Int32 ASCII = num1;
num =num+ ((char)num1);
}
Console.WriteLine(num);
}
catch
{
Console.WriteLine(a);
}
if (length == -1)
break;
}
}
static Random _r = new Random();
static int Number()
{
return _r.Next(65, 90); // decimal
}
}
you can try this one
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PasswordSample
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Generated password: {0}", GeneratePassword(12, true));
}
/// <summary>
/// Generate a random password
/// </summary>
/// <param name="pwdLenght">Password lenght</param>
/// <param name="nonAlphaNumericChars">Indicates if password will include non alpha-numeric</param>
/// <returns>Return a password</returns>
private static String GeneratePassword(int pwdLenght, bool nonAlphaNumericChars)
{
// Allowed characters
String allowedChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
if (nonAlphaNumericChars)
{
// Add non-alphanumeric chars
allowedChars += "-&##%!*$?_";
}
char[] passwordChars = new char[pwdLenght];
Random rnd = new Random();
// Generate a random password
for (int i = 0; i < pwdLenght; i++)
passwordChars[i] = allowedChars[rnd.Next(0, allowedChars.Length)];
return new String(passwordChars);
}
}
}
just define a string at near int x...
like
String Password = "";
and in the if statement appent the keyyword.
if (length > 0)
{
Console.WriteLine(num);
Password+=num
}
I found the following post useful when I had to create a method to generate a random password:
https://stackoverflow.com/a/730352/1015289
However, when I wanted to create a short 'validation' style code which would be emailed to a user to confirm their details, I wanted to restrict the validation code to only 8 characters.
For this I used the following:
string validationCoce = Guid.NewGuid().ToString().Substring(0, 8);
This would be stored in a database which also held the users email, both encrypted before being stored for security purposes.
Both the email and validation code were required to validate the users account.
Hope either of the above help?
Kind Regards, Wayne
use Console.Write() instead of Console.WriteLine() otherwise append to some string and print outside the loop

Categories

Resources