Related
This question already has answers here:
Convert integer to hexadecimal and back again
(11 answers)
Closed 1 year ago.
So my class assignment is to make our own algorithm not using the built in functions that converts an int to hexidecimal and for the life of me it will not comply.
The example in our text converts 24032 to 0x5DE0 but what I am getting as output is 3210.
This is my code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
List<string> errorList = new List<string>();
List<int> hexList = new List<int>();
string intInput = "";
string msgOutput = "";
private void btn_Hex_Click(object sender, EventArgs e)
{
intInput = box_Int.Text;
int toHexFunc = Validator(intInput);
ToHex(toHexFunc);
}
public void ToHex(int fromHexBtn)
{
int n = fromHexBtn;
char[] hexNum = new char[100];
int i = 0;
while (n != 0)
{
int iterTemp = n % 16;
// using ASCII table from https://www.dotnetperls.com/ascii-table
if (iterTemp < 10)
{
hexNum[i] = (char)(iterTemp + 48);
i++;
}
else
{
hexNum[i] = (char)(iterTemp + 55);
i++;
}
n = n / 16;
}
for (int j = i - 1; j >= 0; j--)
{
hexList.Add(j);
}
msgOutput = String.Join("", hexList);
lbl_Message.Text = msgOutput;
}
}
base on this https://www.permadi.com/tutorial/numDecToHex/
class Program
{
static void Main(string[] args)
{
var characters = "0123456789ABCDEF";
int number = 24032;
var hexidecimal = "";
while (number > 0)
{
var remainder = number % 16;
var res = Math.Abs(number / 16);
hexidecimal = characters[remainder] + hexidecimal;
number = res;
}
hexidecimal = "0x" + hexidecimal;
WriteLine(hexadecimal);
}
}
Hoping I can explain this clearly ... I have a collection of variables:
static string sRunnerSetName, sFH, sR1, sH2, sR2, sH3, sR3, sH4, sR4, sH5, sR5 = "";
static int iRunnerSetName, iFH, iR1, iH2, iR2, iH3, iR3, iH4, iR4, iH5, iR5 = 0;
Each of the int variables hold a unique value, which provide the order that the corresponding string variables need to be combined and put into a concatenated string. So iFH holds the sorting/order-number position for where the string sFH will be positioned in the concatenated string.
I'm just stuck with how to use the values in each int to create the order of strings?
As an example -
iFH = 2; i1R = 0; i2R = 1;
sFH = "z"; s1R = "x"; s2R = "y";
Looking to use the values in the integer variables to create the order/position of each string so that the concatenated result of the above would be "xyz".
Create a class holding a string and an int:
class Item
{
public string Description {get;set;}
public int SortOrder {get;set;}
}
Create a list (or another collection, which fits better to your needs) of these items:
List<Item> list = new List<Item>
{
new Item { Description = "Test", SortOrder = 4 },
new Item { Description = "Test2", SortOrder = 3 },
new Item { Description = "sadf", SortOrder = 1 },
new Item { Description = "Example", SortOrder = 2 },
new Item { Description = "something", SortOrder = 5 }
};
You can use LINQ to sort your list:
list = list.OrderBy(x => x.SortOrder).ToList();
You can then output it on console:
Console.WriteLine(string.Join("\n", list.Select(x => x.Description)));
Try it online
You could use arrays here; copy the data into the arrays, then sort them using the index one as the master:
string a = "a", b = "b", c = "c", d = "d";
int ia = 3, ib = 2, ic = 0, id = 1;
string[] sarr = null;
int[] iarr = null;
try
{
// put the data into vectors; we can't talk about variables
// abstractly, but we *can* talk about vectors by position
sarr = ArrayPool<string>.Shared.Rent(4);
iarr = ArrayPool<int>.Shared.Rent(4);
sarr[0] = a;
sarr[1] = b;
sarr[2] = c;
sarr[3] = d;
iarr[0] = ia;
iarr[1] = ib;
iarr[2] = ic;
iarr[3] = id;
var sb = new StringBuilder();
Array.Sort(iarr, sarr, 0, 4);
for (int i = 0; i < 4; i++)
{
sb.Append(sarr[i]);
}
sb.AppendLine();
Console.WriteLine(sb.ToString());
}
finally
{
if (sarr is not null) ArrayPool<string>.Shared.Return(sarr);
if (iarr is not null) ArrayPool<int>.Shared.Return(iarr);
}
Not super efficient, but it would work. However, it is probably better to re-frame the problem; from your example:
iFH = 2; i1R = 0; i2R = 1;
sFH = "z"; s1R = "x"; s2R = "y";
If we instead say:
string[] sarr = { "z", "x", "y"};
and now talk in terms of what tokens you want, by position:
int[] iarr = { 1, 2, 0 };
now you can just use:
foreach (int i in iarr) {
sb.Append(sarr[i]);
}
One possible solution: use a SortedDictionary<int, string> like this:
int iFH = 2, i1R = 0, i2R = 1;
string sFH = "z", s1R = "x", s2R = "y";
var map = new SortedDictionary<int, string>();
map[iFH] = sFH;
map[i1R] = s1R;
map[i2R] = s2R;
var result = string.Join("", map.Values);
If I understand correctly, you mean to use the int values as order number in an array of strings. Since the int values are of type int, you could directly use them as values. For Example, assuming you have an array of strings called stringArray,
stringArray[iFH] = sFH;
Doing this for all the strings you can make an ordered array. To concatenate them all, you can iterate over the array and add them to a seperate string in the following way:
String finalString = "";
for(int i = 0; i < stringArray.Length; i++){
finalString = finalString + stringArray[i];
}
console.WriteLine(finalString);
Splitting the problem into two
Converting an arbitrarily long random list of variables into an
array
Using the array to create a concatenated string
For part 1, create a function that takes params
public static string[] StringList(params object[] stringValues) => stringValues.Cast<string>().ToArray();
public static int[] PositionList(params object[] intValues) => intValues.Cast<int>().ToArray();
For part 2
public static string Join(string[] text, int[] positions)
{
string[] final = new string[text.Length];
for (int i = 0; i < text.Length; i++)
{
final[positions[i]] = text[i];
}
return string.Join("", final);
}
Then run like this:
public static string RunExample()
{
string sFH = "z"; string s1R = "x"; string s2R = "y";
int iFH = 2; int i1R = 0; int i2R = 1;
return Join(StringList(sFH, s1R, s2R), PositionList(iFH, i1R, i2R));
}
Entire example:
public static class Joiner
{
public static string[] StringList(params object[] stringValues) => stringValues.Cast<string>().ToArray();
public static int[] PositionList(params object[] intValues) => intValues.Cast<int>().ToArray();
public static string Join(string[] text, int[] positions)
{
string[] final = new string[text.Length];
for (int i = 0; i < text.Length; i++)
{
final[positions[i]] = text[i];
}
return string.Join("", final);
}
public static string RunExample()
{
string sFH = "z"; string s1R = "x"; string s2R = "y";
int iFH = 2; int i1R = 0; int i2R = 1;
return Join(StringList(sFH, s1R, s2R), PositionList(iFH, i1R, i2R));
}
}
You can add your own code for exception handling (mismatch in array sizes etc).
I would like to allow users to choose the exact length, or less than / more than count o characters to be generated (in a password generator).
For example i have done:
// the longivity of the generated string
var stringChars = new char[int.Parse(TextBox2.Text)];
var random = new Random();
for (int i = 0; i < stringChars.Length; i++)
{
// abc has been declared before, it is simply ABCD... for character generation
stringChars[i] = abc[random.Next(abc.Length)];
}
var finalString = new String(stringChars);
// this is the result box
TextBox1.Text = finalString;
Now my problem is if user enters for eg. 10 and wants less than 10 characters of generated string, what should I do?
You could do for example something like this (with the power of Linq):
public string GeneratePassword(string abc, int minLenght, int maxLenght)
{
var random = new Random();
var chars = Enumerable
.Range(0, random.Next(minLenght, maxLenght + 1)) // Generate a range between the min and max.
.Select(x => abc[random.Next(abc.Length)]) // Select a random character from the abc.
.ToList();
// Concatenate the string.
return string.Join(string.Empty, chars);
}
You have to using the System.Linq
Usage:
var input = 10;
var abc = "abcde";
var maxPasswordLength = 100;
var minPasswordLength = 1;
// More than the input.
GeneratePassword(abc, input + 1, maxPasswordLength);
// Less than the input.
GeneratePassword(abc, minPasswordLength, input - 1);
// Exact length.
GeneratePassword(abc, input, input);
public class Program
{
private const int MAX_LENGTH = 50;
static void Main(string[] args)
{
var less = GeneratedLessThan(12);
var more = GeneratedMoreThan(12);
Console.WriteLine($"Less Than : {less} ({less.Length})");
Console.WriteLine($"More Than : {more} ({more.Length})");
Console.ReadLine();
}
static char[] ABC()
{
List<char> list = new List<char>();
for (char i = 'A'; i <= 'Z'; i++)
{
list.Add(i);
}
return list.ToArray();
}
static string GeneratedLessThan(int max) => GeneratedString(0, max);
static string GeneratedMoreThan(int min) => GeneratedString(min, MAX_LENGTH);
static string GeneratedString(int min, int max)
{
StringBuilder builder = new StringBuilder();
var abc = ABC();
var rnd = new Random();
for (int i = 0; i <= rnd.Next(min, max); i++)
{
builder.Append(abc[rnd.Next(abc.Length)]);
}
return builder.ToString();
}
}
Maybe you dont need ABC function.
Ouput :
Less Than : IORS (4)
More Than : BSVPFZVQRWZTSPYDI (17)
I am currently trying to make a random password generator.
My code works fine if I only pick one type of symbols.
What's the best way to make my code to word for more than one type?
Also what parameters would you add to make the password more secured?
I am thinking of adding an if loop to check if there are more than two same letters, symbols or numbers in a row.
That's how my interface looks like:
and that is my code:
public partial class Form1 : Form
{
// Max number of identical characters in a row
const int Maximum_Identical = 2;
// lower case chars
const string lower_chars = "abcdefghijklmnopqrstuvwxyz";
// capital chars
const string capital_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// numbers
const string numbers = "0123456789";
// symbols
const string symbols = #"!#$%&*#\";
// password lenght
int lenght;
private void button1_Click(object sender, EventArgs e)
{
//use stringbuilder so I can add more chars later
StringBuilder password = new StringBuilder();
//take max lenght from numericUpDown
lenght = Convert.ToInt32(numericUpDown1.Value);
// random instance so I can use Next and don't get loops
Random rdm = new Random();
if (small_letters__Box.Checked)
{
//add a random small character to pass untill it reaches the selected lenght
while (lenght-- > 0 )
{
password.Append(lower_chars[rdm.Next(lower_chars.Length)]);
}
}
if (capital_letters__Box.Checked)
{
//add a random capital character to pass untill it reaches the selected lenght
while (lenght-- > 0)
{
password.Append(capital_chars[rdm.Next(capital_chars.Length)]);
}
}
if (numbers_Box.Checked)
{
//add a random character to pass untill it reaches the selected lenght
while (lenght-- > 0)
{
password.Append(numbers[rdm.Next(numbers.Length)]);
}
}
if (symbols_Box.Checked)
{
//add a random character to pass untill it reaches the selected lenght
while (lenght-- > 0)
{
password.Append(symbols[rdm.Next(symbols.Length)]);
}
}
textBox1.Text = password.ToString();
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
}
}
Your password generation has 2 steps.
Determine the character set
Create a password randomly from the character set of length n
Function 1 creates the character set:
// Make sure you have using System.Linq;
private List<char> GetCharacterSet()
{
IEnumerable<char> returnSet = new char[]{};
if (small_letters__Box.Checked)
{
returnSet = returnSet.Append(lower_chars);
}
if (capital_letters__Box.Checked)
{
returnSet = returnSet.Append(capital_chars);
}
if (numbers_Box.Checked)
{
returnSet = returnSet.Append(numbers);
}
if (symbols_Box.Checked)
{
returnSet = returnSet.Append(symbols);
}
return returnSet.ToList();
}
Function 2 creates a password of given length from your character set
private string GetPassword(int length, List<char> characterSet)
{
if(characterSet.Count < 1)
{
throw new ArgumentException("characterSet contains no items!");
}
if(length < 1)
{
return "";
}
Random rdm = new Random();
StringBuilder password = new StringBuilder();
for(int i = 0; i < length; i++){
int charIndex = rdm.Next(0, characterSet.Count)
password.Append(characterSet[charIndex]);
}
return password.ToString();
}
Then simply rig your button click event handler to call these functions and display the resulting password.
below code is my already written code which I wrote more than a couple of years ago and I still use it in my many of my projects where needed, it covers all you are in need of
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading;
public static class ArrayExtentions
{
public static object[] Shuffle(this object[] array)
{
var alreadySwaped = new HashSet<Tuple<int, int>>();
var rndLoopCount = RandomUtils.GetRandom(Convert.ToInt32(array.Length / 4), Convert.ToInt32((array.Length / 2) + 1));
for (var i = 0; i <= rndLoopCount; i++)
{
int rndIndex1 = 0, rndIndex2 = 0;
do
{
rndIndex1 = RandomUtils.GetRandom(0, array.Length);
rndIndex2 = RandomUtils.GetRandom(0, array.Length);
} while (alreadySwaped.Contains(new Tuple<int, int>(rndIndex1, rndIndex2)));
alreadySwaped.Add(new Tuple<int, int>(rndIndex1, rndIndex2));
var swappingItem = array[rndIndex1];
array[rndIndex1] = array[rndIndex2];
array[rndIndex2] = swappingItem;
}
return array;
}
}
public class RandomUtils
{
private static readonly ThreadLocal<Random> RndLocal = new ThreadLocal<Random>(() => new Random(GetUniqueSeed()));
private static int GetUniqueSeed()
{
long next, current;
var guid = Guid.NewGuid().ToByteArray();
var seed = BitConverter.ToInt64(guid, 0);
do
{
current = Interlocked.Read(ref seed);
next = current * BitConverter.ToInt64(guid, 3);
} while (Interlocked.CompareExchange(ref seed, next, current) != current);
return (int)next ^ Environment.TickCount;
}
public static int GetRandom(int min, int max)
{
Contract.Assert(max >= min);
return RndLocal.Value.Next(min, max);
}
public static int GetRandom(int max)
{
return RndLocal.Value.Next(max);
}
public static double GetRandom()
{
return RndLocal.Value.NextDouble();
}
}
public class StringUtility
{
private const string UpperAlpha = "ABCDEFGHIJKLMNOPQRSTUWXYZ";
private const string LowerAlpha = "abcdefghijklmnopqrstuwxyz";
private const string Numbers = "0123456789";
private const string SpecialChars = "~!##$%^&*()_-+=.?";
private static string CreateSourceString(bool includeLowerCase, bool includeUpperCase, bool includenumbers, bool includeSpChars)
{
Contract.Assert(includeLowerCase || includeUpperCase || includenumbers || includeSpChars);
var sb = new StringBuilder();
if (includeLowerCase) sb.Append(LowerAlpha);
if (includeUpperCase) sb.Append(UpperAlpha);
if (includenumbers) sb.Append(Numbers);
if (includeSpChars) sb.Append(SpecialChars);
return sb.ToString();
}
private static string GenerateString(string sourceString, int length = 6)
{
var rndString = Shuffle(sourceString);
var builder = new StringBuilder();
for (var i = 0; i < length; i++)
builder.Append(rndString[RandomUtils.GetRandom(0, rndString.Length)]);
return builder.ToString();
}
public static string GenerateRandomString(int length = 6,
bool includenumbers = false,
bool includeSpChars = false)
{
var sourceStr = CreateSourceString(true, true, includenumbers, includeSpChars);
return GenerateString(sourceStr, length);
}
public static string GenerateRandomString(int minLength,
int maxLength,
bool includenumbers = false,
bool includeSpChars = false)
{
if (maxLength < minLength) maxLength = minLength;
var len = RandomUtils.GetRandom(minLength, maxLength + 1);
return GenerateRandomString(len, includenumbers, includeSpChars);
}
public static string Shuffle(string str)
{
var alreadySwaped = new HashSet<Tuple<int, int>>();
var rndLoopCount = RandomUtils.GetRandom(Convert.ToInt32(str.Length / 4), Convert.ToInt32((str.Length / 2) + 1));
var strArray = str.ToArray();
for (var i = 0; i <= rndLoopCount; i++)
{
int rndIndex1 = 0, rndIndex2 = 0;
do
{
rndIndex1 = RandomUtils.GetRandom(0, str.Length);
rndIndex2 = RandomUtils.GetRandom(0, str.Length);
} while (alreadySwaped.Contains(new Tuple<int, int>(rndIndex1, rndIndex2)));
alreadySwaped.Add(new Tuple<int, int>(rndIndex1, rndIndex2));
var swappingChar = strArray[rndIndex1];
strArray[rndIndex1] = strArray[rndIndex2];
strArray[rndIndex2] = swappingChar;
}
return new string(strArray);
}
public static string GeneratePassword(PasswordComplexity complexityLevel)
{
switch (complexityLevel)
{
case PasswordComplexity.Simple: return GenerateSimplePassword();
case PasswordComplexity.Medium: return GenerateMediumPassword();
case PasswordComplexity.Strong: return GenerateStrongPassword();
case PasswordComplexity.Stronger: return GenerateStrongerPassword();
}
return null;
}
private static string GenerateSimplePassword()
{
return GenerateRandomString(6, 9);
}
private static string GenerateMediumPassword()
{
var passLen = RandomUtils.GetRandom(6, 10);
var numCount = RandomUtils.GetRandom(1, 3);
var alphaStr = GenerateRandomString(passLen - numCount);
var numStr = GenerateString(Numbers, numCount);
var pass = alphaStr + numStr;
return Shuffle(pass);
}
private static string GenerateStrongPassword()
{
var lowerCharCount = RandomUtils.GetRandom(2, 5);
var upperCharCount = RandomUtils.GetRandom(2, 5);
var numCount = RandomUtils.GetRandom(2, 4);
var spCharCount = RandomUtils.GetRandom(2, 4);
var lowerAlphaStr = GenerateString(LowerAlpha, lowerCharCount);
var upperAlphaStr = GenerateString(UpperAlpha, upperCharCount);
var spCharStr = GenerateString(SpecialChars, spCharCount);
var numStr = GenerateString(Numbers, numCount);
var pass = lowerAlphaStr + upperAlphaStr + spCharStr + numStr;
return Shuffle(pass);
}
private static string GenerateStrongerPassword()
{
var lowerCharCount = RandomUtils.GetRandom(5, 12);
var upperCharCount = RandomUtils.GetRandom(4, 8);
var numCount = RandomUtils.GetRandom(4, 6);
var spCharCount = RandomUtils.GetRandom(4, 6);
var lowerAlphaStr = GenerateString(LowerAlpha, lowerCharCount);
var upperAlphaStr = GenerateString(UpperAlpha, upperCharCount);
var spCharStr = GenerateString(SpecialChars, spCharCount);
var numStr = GenerateString(Numbers, numCount);
var pass = lowerAlphaStr + upperAlphaStr + spCharStr + numStr;
return Shuffle(Shuffle(pass));
}
public enum PasswordComplexity
{
Simple, Medium, Strong, Stronger
}
}
I write this code for you. You can just copy and use it. All of my code is just a method that you can pass appropriate arguments and it gives you back a completely randomized password. I test it several times before answering your question, It works well.
private string GeneratePassword(bool useCapitalLetters, bool useSmallLetters, bool useNumbers, bool useSymbols, int passLenght)
{
Random random = new Random();
StringBuilder password = new StringBuilder(string.Empty);
//This for loop is for selecting password chars in order
for (int i = 0;;)
{
if (useCapitalLetters)
{
password.Append((char)random.Next(65, 91)); //Capital letters
++i; if (i >= passLenght) break;
}
if (useSmallLetters)
{
password.Append((char)random.Next(97, 122)); //Small letters
++i; if (i >= passLenght) break;
}
if (useNumbers)
{
password.Append((char)random.Next(48, 57)); //Number letters
++i; if (i >= passLenght) break;
}
if (useSymbols)
{
password.Append((char)random.Next(35, 38)); //Symbol letters
++i; if (i >= passLenght) break;
}
}
//This for loop is for disordering password characters
for (int i = 0; i < password.Length; ++i)
{
int randomIndex1 = random.Next(password.Length);
int randomIndex2 = random.Next(password.Length);
char temp = password[randomIndex1];
password[randomIndex1] = password[randomIndex2];
password[randomIndex2] = temp;
}
return password.ToString();
}
an answer with complete randomize char and using the max repeat of char, i have added a shuffle string function:
const int Maximum_Identical = 2; // Max number of identical characters in a row
const string lower_chars = "abcdefghijklmnopqrstuvwxyz"; // lower case chars
const string capital_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //capital chars
const string numbers = "0123456789"; //numbers
const string symbols = #"!#$%&*#\"; //symbols
int lenght = 6; //
bool lowercase = true, capital=true, num=true, sym=true;
List<char[]> PasswordSet = new List<char[]>();
List<char[]> charSet = new List<char[]>();
List<int[]> countSet = new List<int[]>();
if (lowercase) charSet.Add(lower_chars.ToArray());
if (capital) charSet.Add(capital_chars.ToArray());
if (num) charSet.Add(numbers.ToArray());
if (sym) charSet.Add(symbols.ToArray());
foreach(var c in charSet)
countSet.Add(new int[c.Length]);
Random rdm = new Random();
//we create alist with each type with a length char (max repeat char included)
for(int i = 0; i < charSet.Count;i++)
{
var lng = 1;
var p0 = "";
while (true)
{
var ind = rdm.Next(0, charSet[i].Length);
if (countSet[i][ind] < Maximum_Identical )
{
countSet[i][ind] += 1;
lng++;
p0 += charSet[i][ind];
}
if (lng == lenght) break;
}
PasswordSet.Add(p0.ToArray());
}
//generate a password with the desired length with at less one char in desired type,
//and we choose randomly in desired type to complete the length of password
var password = "";
for(int i = 0; i < lenght; i++)
{
char p;
if (i < PasswordSet.Count)
{
int id;
do
{
id = rdm.Next(0, PasswordSet[i].Length);
p = PasswordSet[i][id];
} while (p == '\0');
password += p;
PasswordSet[i][id] = '\0';
}
else
{
int id0;
int id1;
do
{
id0 = rdm.Next(0, PasswordSet.Count);
id1 = rdm.Next(0, PasswordSet[id0].Length);
p = PasswordSet[id0][id1];
} while (p == '\0');
password += p;
PasswordSet[id0][id1] = '\0';
}
}
//you could shuffle the final password
password = Shuffle.StringMixer(password);
shuffle string function:
static class Shuffle
{
static System.Random rnd = new System.Random();
static void Fisher_Yates(int[] array)
{
int arraysize = array.Length;
int random;
int temp;
for (int i = 0; i < arraysize; i++)
{
random = i + (int)(rnd.NextDouble() * (arraysize - i));
temp = array[random];
array[random] = array[i];
array[i] = temp;
}
}
public static string StringMixer(string s)
{
string output = "";
int arraysize = s.Length;
int[] randomArray = new int[arraysize];
for (int i = 0; i < arraysize; i++)
{
randomArray[i] = i;
}
Fisher_Yates(randomArray);
for (int i = 0; i < arraysize; i++)
{
output += s[randomArray[i]];
}
return output;
}
}
There you go :
string[] charList =
{
"abcdefghijklmnopqrstuvwxyz",
"ABCDEFGHIJKLMNOPQRSTUVWXYZ",
"0123456789",
"#\"!#$%&*#\\"
};
int desiredPasswordLength = 12;
var randomNumberGenerator = new Random();
string generatedPassword = "";
for (int i = randomNumberGenerator.Next() % 4; desiredPasswordLength > 0; i = (i+1) % 4)
{
var takeRandomChars = randomNumberGenerator.Next() % 3;
for (int j = 0; j < takeRandomChars; j++)
{
var randomChar = randomNumberGenerator.Next() % charList[i].Length;
char selectedChar = charList[i][randomChar % charList[i].Length];
generatedPassword = string.Join("", generatedPassword, selectedChar);
}
desiredPasswordLength -= takeRandomChars;
}
Console.WriteLine("Generated password: {0}",generatedPassword);
private static string GeneratorPassword(UInt16 length = 8)
{
const string chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0";
System.Text.StringBuilder sb = new System.Text.StringBuilder();
Random rnd = new Random();
System.Threading.Thread.Sleep(2);
for (int i = 0; i < length; i++)
{
int index = 0;
if (i % 3 == 0)
{
index = rnd.Next(0, 10);
}
else if (i % 3 == 1)
{
index = rnd.Next(10, 36);
}
else
{
index = rnd.Next(36, 62);
}
sb.Insert(rnd.Next(0, sb.Length), chars[index].ToString());
}
return sb.ToString();
}
static void Main(string[] args)
{
for (int j= 0; j < 100; j++)
{
Console.WriteLine( GeneratorPassword());
}
Console.ReadLine();
}
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.