I created a random password generator with in a windows form.
The user will select the length of the password and the number of passwords which will be generated in a Richtextbox.
The problem arises when i want to generate more than 1 password.
It does not generate more than 1 password at a time no matter how i do it.
Posting code below.
string passwords = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890?!/#£#$%&[]+``^~*";
Random pass = new Random();
string passwordline { get; set; }
private void button1_Click(object sender, EventArgs e)
{
passwordline = "";
int passwordsNum = (int)numericUpDown1.Value;
int passwordLength = (int)numericUpDown2.Value;
int length = 0;
for (int i = 0; i<passwordsNum; i++)
{
for (int i2 = 0; i2 < passwordLength; i2++)
{
int randomnumbers = pass.Next(passwords.Length);
passwordline += passwords[randomnumbers];
length++;
if (passwordline.Length == passwordLength)
{
richTextBox1.Text += passwordline + Environment.NewLine;
}
}
}
}
It seems that it could be that you are not resetting the password to empty with every new run. Try changing code to this:
for (int i = 0; i<passwordsNum; i++)
{
passwordline = "";
for (int i2 = 0; i2 < passwordLength; i2++)
{
//Other code is the same
}
}
You simply need to add a new line between two passwords, now you generate sequences of characters you "concatenate" into one password (and remove some errors):
string passwordline = "";
int passwordsNum = (int)numericUpDown1.Value;
int passwordLength = (int)numericUpDown2.Value;
for (int i = 0; i<passwordsNum; i++) {
passwordline = "";
for (int i2 = 0; i2 < passwordLength; i2++) {
int randomnumbers = pass.Next(passwords.Length);
passwordline += passwords[randomnumbers];
}
richTextBox1.Text += passwordline+"\n";
}
The code is also more optimized: you use an if statement in your for-loop, while this code is never executed and simply should be executed at the end of your statement.
Related
I want to generate 1000 number randomly and put the result in a rich text box ,but the result I got from my code is just one number appearing in the rich text box !!
private Random _random = new Random();
int min = 000000;
int max = 999999;
string s;
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 1000; i++)
{
s = _random.Next(min, max).ToString("D6") + "\n";
}
richTextBox1.Text = s;
}
You are overriding the value of s each time you get your next number. Instead you have to add the number to a list. Something like this would work.
List<string> numbers = new List<string>();
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 1000; i++)
{
numbers.Add(_random.Next(min, max).ToString("D6"));
}
richTextBox1.Text = string.Join(Environment.NewLine, numbers);
}
As most of the answers here using the .net class Random i would not use it, because in a direct comparison it doesn't creates strong random numbers.
Example:
So if you want strong random numbers you should refrain from using Random and use the RNGCryptoServiceProvider from the namesapace System.Security.Cryptography
ExampleCode:
private RNGCryptoServiceProvider _random = new RNGCryptoServiceProvider ();
int min = 000000;
int max = 999999;
private void Form1_Load(object sender, EventArgs e)
{
int[] results = new int[1000];
var buffer = new byte[4];
int min = 100000;
int max = 999999;
for (int i = 0; i < results.Length; i++) {
while(results[i] < min || results[i] > max)
{
_random.GetBytes(buffer);
results[i] = BitConverter.ToInt32(buffer, 0);
}
richTextBox1.Text += results[i].toString();
}
}
You actually need to concatenate the result with previous calculated result, right now it is replacing the string value in s every time loop executes and you end up only with the last value in s, a quick fix is to use contatination using +:
for (int i = 0; i < 1000; i++)
{
s+= _random.Next(min, max).ToString("D6") + "\n"; // now it keeps previous values as well
}
Problem is that you actually overwrite at each iteration the string s. You need to append the number to the old ones.
for (int i = 0; i < 1000; i++)
{
s += _random.Next(min, max).ToString("D6") + "\n";
}
richTextBox1.Text = s;
You could also use AppendText method
for (int i = 0; i < 1000; i++)
{
richTextBox1.AppendText(_random.Next(min, max).ToString("D6") + "\n");
}
Suggestion by Matthew Watson: When generating such a large string it is very adviseable to use a StringBuilder. Is has much better performance than a normal concatenation of strings:
StringBuilder sb = new StringBuilder(8000);
for (int i = 0; i < 1000; i++)
{
sb.AppendLine(_random.Next(min, max).ToString("D6"));
}
richTextBox1.Text = sb.ToString();
s += _random.Next(min, max).ToString("D6") + "\n";
^
|
---- You're missing this plus sign
on this line of code you override the Text of richTextBox1
for (int i = 0; i < 1000; i++)
{
s = _random.Next(min, max).ToString("D6") + "\n";
}
richTextBox1.Text = s;
just change it to (add a + after s)
for (int i = 0; i < 1000; i++)
{
s += _random.Next(min, max).ToString("D6") + "\n";
}
richTextBox1.Text = s;
Note that the maxValue or Random.Next is exclusive, so 999999 is never genereted.
var numbers = Enumerable.Repeat(new Random(), 1000)
.Select(r => r.Next(1000000).ToString("D6")); // the same new Random() instance is used for all .Next
richTextBox1.Text = string.Join("\r\n", numbers);
Or a bit more efficient:
richTextBox1.Text = Enumerable.Repeat(new Random(), 1000).Aggregate(new StringBuilder(7000)
, (b, r) => b.AppendFormat("{0:D6}\n", r.Next(1000000))).ToString(0, 6999);
just You need to add ' + ' for the richtextbox1 as like below
try this one
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < 1000; i++)
{
s = _random.Next(min, max).ToString("D6") + "\n";
richTextBox1.Text + = s;
}
}
So i'm trying to make a program that uses the League of Legends API in C#.
I found a NuGet package that makes using the API a lot easier.
Everything works fine so far except the code execution stops after the
first for loop i use.
Here's the code: (of course i took out the api key)
string[] summnames;
long[] champids;
long[] teamids;
long[] champs;
CreepScoreAPI.ParticipantLive[] enemy;
CreepScoreAPI.ParticipantLive[] ally;
CreepScoreAPI.ParticipantLive centsumm;
CreepScoreAPI.ParticipantLive[] champsss;
CreepScoreAPI.ChampionStatic[] champions;
CreepScoreAPI.Summoner[] sumners;
CreepScoreAPI.League[] leaguesz;
Dictionary<string, List<CreepScoreAPI.League>>[] leagues;
int[] champidsint;
string[] champnames;
int s;
int se;
public async Task<string> game(string summname)
{
string data;
CreepScoreAPI.CreepScore cs = new CreepScoreAPI.CreepScore("api key");
var summoner = await cs.RetrieveSummoner(CreepScoreAPI.CreepScore.Region.EUNE, summname);
long summid = summoner.id;
var thegame = await summoner.RetrieveCurrentGameInfo();
CreepScoreAPI.ParticipantLive[] participants = thegame.participants.ToArray();
for (int i = 0; i <= 9; i++) { summnames[i] = participants[i].summonerName;}
for (int i = 0; i <= 9; i++) { champids[i] = participants[i].championId;}
for (int i = 0; i <= 9; i++) { teamids[i] = participants[i].teamIdLong;}
for (int i = 0; i <= 9; i++) { champids[i] = participants[i].championId;}
for (int i = 0; i <= 9; i++) { champidsint[i] = Convert.ToInt32(champids[i]);}
for (int i = 0; i <= 9; i++) { champions[i] = await cs.RetrieveChampionData( CreepScoreAPI.CreepScore.Region.EUNE, champidsint[i], CreepScoreAPI.Constants.StaticDataConstants.ChampData.All, "en_US", "7.1.1",false ); }
for (int i = 0; i <= 9; i++) { champnames[i] = champions[i].name; }
for (int i = 0; i <= 9; i++) { sumners[i] = await cs.RetrieveSummoner(CreepScoreAPI.CreepScore.Region.EUNE, summnames[i]); }
for (int i = 0; i <= 9; i++) { leagues[i] = await sumners[i].RetrieveLeague(); }
/* teamsorter */
foreach (CreepScoreAPI.ParticipantLive p in participants)
{
if (p.summonerId == summid)
{
centsumm = p;
}
if (p.teamIdLong == centsumm.teamIdLong)
{
ally[s] = p;
s++;
}
if (p.teamIdLong != centsumm.teamIdLong)
{
enemy[se] = p;
se++;
}
}
data = " I'LL FORMAT A STRING THAT OUTPUTS ALL THE DATA I NEED HERE";
return data;
}
When I call the game function and input the name of the summoner i gets to the first for loop and doesn't even populate the summnames[] array and stops execution with no error code.
What I'm trying to do with all the loops is populate the variables I made before the function so I can use them later for other purposes.
I think you should assign all the arrays and set their length to at least 10.
This could solve the problem.
I'm having trouble randomizing X-amounts of strings and adding them to my listbox. it keeps adding the same string over and over. i want it to add 1 line per string. if i say that amount is 11, it just makes one string and adds it 11 times to listbox. what am i doing wrong?
here is my code:
for (int i = 0; i < amount; i++)
{
Random adomRng = new Random();
string rndString = string.Empty;
char c;
for (int t = 0; t < 8; t++)
{
while (!Regex.IsMatch((c = Convert.ToChar(adomRng.Next(48, 128))).ToString(), "[a-z0-9]")) ;
rndString += c;
}
listBox1.Items.Add(rndString);
}
Random adomRng = new Random();
for (int i = 0; i < amount; i++)
{
string rndString = string.Empty;
char c;
for (int t = 0; t < 8; t++)
{
while (!Regex.IsMatch((c = Convert.ToChar(adomRng.Next(48, 128))).ToString(), "[a-z0-9]")) ;
rndString += c;
}
listBox1.Items.Add(rndString);
}
Put the random init code outside of the loop, it will get you the correct result
Explanation: creating multiple new random objects in the short period of time (let's say inside a for loop) will always give you the same output because it will use the current timestamp as random seed.
You are almost there,just make two simple changes in your code to achieve the target:
for (int t = 0; t < 8; t++)
{
rndString =""; //Change 1
while (!Regex.IsMatch((c = Convert.ToChar(adomRng.Next(48, 128))).ToString(), "[a-z0-9]")) ;
rndString += c;
listBox1.Items.Add(rndString);// change 2
}
I really need a solution for the next scenario(I've been searching for hours and beating about the bushes to find a smooth solution, but none worked):
I have a winform that:
parse a text file
generate some folders using random words from that file
My code so far:
int value;
string path = null;
private void button1_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog(this) == DialogResult.OK)
{
path = fbd.SelectedPath;
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
value = Convert.ToInt32(textBox1.Text);//store the value from the textbox in variable "value"
}
private void button2_Click(object sender, EventArgs e)
{
if (path != null && Directory.Exists(path))
for (int i = 0; i < value; i++)
{
Random rnd = new Random();
string tick1 = rnd.Next(0, 10).ToString();
var lines = File.ReadAllLines(#"M:\\dictionar.txt");
var r = new Random(DateTime.Now.Millisecond);
var randomLineNumber = r.Next(0, lines.Length - 1);
var line = lines[randomLineNumber];
StringBuilder b = new StringBuilder();
for (int j = 0; j < line.Length; j++)
{
char c = line[j];
if (rnd.Next(2) == 0)
{
c = Char.ToUpper(c);
}
b.Append(c);
if (j % 3 == 2)
{
b.Append(rnd.Next(10));
}
}
line = b.ToString();
Directory.CreateDirectory(Path.Combine(path, string.Format("{0}", line.Insert(2, tick1).Insert(4, tick1).Insert(6, tick1))));
}
}
Is there a way to use ToUpper() method as line.Insert() one so that I can get random upper letters? More, is there a better way of randomizing those index positions form line.Insert() (I'm asking this because when it's generating the folders name: the indexes are the same: e.g pe8rs8on8al and just after that the index changes.)?
I want to achieve the following:
if I have the next words in the .txt file:
personal
football
programming
computer
I would like the folder names to look like:
Pe3rs9oN1al
fO8ot5Ba6lL
You can loop through the characters in the string and build a new string depending on random values:
StringBuilder b = new StringBuilder();
for (int i = 0; i < line.Length; i++ ) {
char c = line[i];
if (rnd.Next(2) == 0) {
c = Char.ToUpper(c);
}
b.Append(c);
if (i % 2 == 1) {
b.Append(rnd.Next(10));
}
}
line = b.ToString();
Note: You shouldn't create Random objects in the loop. You should create a single Random object before the loop and use for all random numbers that you need. Creating instances too close in time will make them return the same sequences of random numbers. Also, you don't need to seed the random generator from the clock, the constructor without parameters does that automatically:
Random rnd = new Random();
So, the code in the method would be:
if (path != null && Directory.Exists(path))
Random rnd = new Random();
for (int i = 0; i < value; i++)
{
var lines = File.ReadAllLines(#"M:\\dictionar.txt");
var randomLineNumber = rnd.Next(0, lines.Length);
var line = lines[randomLineNumber];
StringBuilder b = new StringBuilder();
for (int j = 0; j < line.Length; j++)
{
char c = line[j];
if (rnd.Next(2) == 0)
{
c = Char.ToUpper(c);
}
b.Append(c);
if (j % 2 == 1)
{
b.Append(rnd.Next(10));
}
}
line = b.ToString();
Directory.CreateDirectory(Path.Combine(path, line));
}
}
Note the rnd.Next(0, lines.Length) to pick a random line. The upper limit for the random number is not inclusive, so if you use rnd.Next(0, lines.Length - 1) it will never pick the last line.
That's because you are specifying only tick1 in the same loop. If you want to change this, add additional ticks to your code as below:
string tick1 = rnd.Next(0, 10).ToString();
string tick2 = rnd.Next(0, 10).ToString();
string tick3 = rnd.Next(0, 10).ToString();
Then use those in your formatting of the string:
Directory.CreateDirectory(Path.Combine(path, string.Format("{0}", line.Insert(2, tick1).Insert(4, tick2).Insert(6, tick3))))
Like Guffa said you should not use Random in a loop, in all preference you should only instanciate one of it, but I think you could use it like this
public static class StringRandomize
{
static readonly Random rnd = new Random();
static char[] permmitedCharacters { get; set; }
static StringRandomize()
{
List<char> Chars= new List<char>();
for (int i = 48; i < 48+10; i++)
{
Chars.Add((char)i);
}
for (int i = 65; i < 65+26; i++)
{
Chars.Add((char)i);
}
permmitedCharacters = Chars.ToArray();
}
public static string Randomize(string input, double RandomizePercent = 30)
{
StringBuilder result = new StringBuilder();
int index = 0;
while (index < input.Length)
{
if (rnd.Next(0, 100) <= RandomizePercent)
{
if (rnd.Next(0, 100) <= RandomizePercent)
{
result.Append(GenerateCaracter());
}
else
{
if (rnd.Next(0, 100) > 50)
{
result.Append(input.ToLower()[index]);
}
else
{
result.Append(input.ToUpper()[index]);
}
index++;
}
}
else
{
result.Append(input[index]);
index++;
}
}
return result.ToString();
}
private static char GenerateCaracter()
{
return permmitedCharacters[rnd.Next(0, permmitedCharacters.Length)];
}
}
private static void GenerateRandomDirectories(string path, int value)
{
//I'm supposing value is the number of lines that you want
var lines = File.ReadAllLines(#"M:\\dictionar.txt");
Random rnd = new Random();
if (path != null && Directory.Exists(path))
{
for (int i = 0; i < value; i++)
{
Directory.CreateDirectory(path + "\\" + StringRandomize.Randomize(lines[rnd.Next(0,lines.Length)]));
}
}
}
"pers3o7Nal"
"foOtBaLl"
Got like this
public Form1()
{
InitializeComponent();
string content = "";
using (FileStream fs = new FileStream("D:\\names.txt", FileMode.Open, FileAccess.Read))
using (StreamReader sr = new StreamReader(fs))
content = sr.ReadToEnd();
string[] names = content.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
string path = "D:\\RandDirs";
if (!Directory.Exists(path))Directory.CreateDirectory(path) ;
for (int i = 0; i < 50; i++) Directory.CreateDirectory(path + "\\" + getRandomName(names));
}
Random randName = new Random();
Random insertingNumber = new Random();
Random randUpper = new Random();
Random randInsertNumber = new Random();
string getRandomName(string[] names)
{
string name = names[randName.Next(names.Length)];
name = name.Replace(" ", "");
string result = "";
for (int i = 0; i < name.Length; i++)
result += (randUpper.Next(0, 9) <= 5 ? name[i].ToString().ToLower() : name[i].ToString().ToUpper())
+ (((i + 1) % 2 == 0) ? insertingNumber.Next(0, 9).ToString() : "");
return result;
}
as per your needs, i've changed from randomly inserting numbers to inserting number every 2 characters.
I have gone through my code and tried to make it as efficient as i can think possible. Still i can not get this program to run all the way through without freezing my box. The maximum amount of time that i have let it run without it freezing it was about 2 hours. I can not believe this did not execute in that amount of time.
Is it an issue with my computer or is this brute force method of solving this problem that inefficient.
What are some ways that i can avoid this type of inefficiency when writing methods in the future?
private void Form1_Load(object sender, EventArgs e)
{
ArrayList listOfAbundantNumbers = new ArrayList();
ArrayList listOfSums = new ArrayList();
long total = 0;
for (int i = 1; i < 20162; i++)
{
if (isAbundandt(i))
{
listOfAbundantNumbers.Add(i);
}
total+=i;
}
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
{
for (int a = 0; a < listOfAbundantNumbers.Count; a++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
long temp2 = Convert.ToInt64(listOfAbundantNumbers[a]);
long num = temp1 + temp2;
if(listOfSums.Contains(num) == false)
{
listOfSums.Add(num);
}
}
}
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
total -= temp1;
}
printLn(total + "");
}
private ArrayList divisorList(long input)
{
ArrayList divisors = new ArrayList();
for (long i = 2; i < Math.Round(Math.Sqrt(input),0,0); i++)
{
long temp = input % i;
if (temp == 0)
{
divisors.Add(i);
divisors.Add(input / i);
}
}
return divisors;
}
private Boolean isAbundandt(long input)
{
long sum = 0;
ArrayList divisor = divisorList(input);
for (int i = 0; i < divisor.Count; i++)
{
long temp1 = Convert.ToInt64(divisor[i]);
sum += temp1;
}
sum++;
if (sum > input)
{
return true;
}
return false;
}
Avoid using ArrayList, prefer generic collection such as List<Int64> because you conversion may be quite expensive.
There is a part in your program which is in O(n^3). It can be reduce to O(n^2) easily. Just replace the following code (O(n) because of List<T>.Contains):
if(listOfSums.Contains(num) == false)
{
listOfSums.Add(num);
}
by:
listOfSums.Add(num);
where listOfSums is now a HashSet<Int64> (it's used to have a collection without duplicates).
Moreover, you can reduce the time for populating the listOfSums by a factor of 2 by just noticing that if you exchange i and a, the sum is the same, then, only one of the two combinations is added to the listOfSums.
You can replace:
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
for (int a = 0; a < listOfAbundantNumbers.Count; a++)
by;
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
for (int a = 0; a <= i; a++)
The final code is:
private static void Main()
{
List<Int64> listOfAbundantNumbers = new List<Int64>();
HashSet<Int64> listOfSums = new HashSet<Int64>();
long total = 0;
for (int i = 1; i < 20162; i++)
{
if (isAbundandt(i))
{
listOfAbundantNumbers.Add(i);
}
total += i;
}
for (int i = 0; i < listOfAbundantNumbers.Count; i++)
for (int a = 0; a <= i; a++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
long temp2 = Convert.ToInt64(listOfAbundantNumbers[a]);
long num = temp1 + temp2;
listOfSums.Add(num);
}
for (int i = 1; i < listOfAbundantNumbers.Count; i++)
{
long temp1 = Convert.ToInt64(listOfAbundantNumbers[i]);
total -= temp1;
}
Console.WriteLine(total + "");
}
private static List<Int64> divisorList(long input)
{
List<Int64> divisors = new List<Int64>();
for (long i = 2; i < Math.Round(Math.Sqrt(input), 0, 0); i++)
{
long temp = input % i;
if (temp == 0)
{
divisors.Add(i);
divisors.Add(input / i);
}
}
return divisors;
}
private static Boolean isAbundandt(long input)
{
long sum = 0;
List<Int64> divisor = divisorList(input);
for (int i = 0; i < divisor.Count; i++)
{
long temp1 = divisor[i];
sum += temp1;
}
sum++;
if (sum > input)
{
return true;
}
return false;
}