I have a string. I want to generate a random string from this string, by replacing a number by a random number. lower character by lower character and upper character by upper character. And remaining characters as it is.
I have written the below code. I need to call this method millions of time on different strings (string length is not more than 100 characters), It's taking too much time.
private static string GenerateRandomAlphanumericValue(string input) {
char[] newStr = new char[input.Length];
char[] alphaU = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
char[] alphaL = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
char[] number = "0123456789".ToCharArray();
Random random = new Random();
for (int i = 0; i < input.Length; i++) {
if (char.IsNumber(input[i])) {
int index = random.Next(0, number.Length);
newStr[i] = number[index];
}
else if (char.IsUpper(input[i])) {
int index = random.Next(0, alphaU.Length);
newStr[i] = alphaU[index];
}
else if (char.IsLower(input[i])) {
int index = random.Next(0, alphaL.Length);
newStr[i] = alphaL[index];
}
else {
newStr[i] = input[i];
}
}
return string.Join("", newStr);
}
I need help in optimizing the code or there any be a different approach to solve the problem.
Input: vivEK123$% ~a
Output: ajrLW854$% ~w
Try this
static char[] alphaU = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
static char[] alphaL = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
static char[] number = "0123456789".ToCharArray();
static Random random = new Random();
static StringBuilder sb = new StringBuilder(100);
private static string GenerateRandomAlphanumericValue(string input)
{
sb.Clear();
for (int i = 0; i < input.Length; i++)
{
if (char.IsNumber(input[i]))
{
int index = random.Next(0, number.Length);
sb.Append(number[index]);
}
else if (char.IsUpper(input[i]))
{
int index = random.Next(0, alphaU.Length);
sb.Append(alphaU[index]);
}
else if (char.IsLower(input[i]))
{
int index = random.Next(0, alphaL.Length);
sb.Append(alphaL[index]);
}
else
{
sb.Append(input[i]);
}
}
return sb.ToString();
}
Instead of using arrays, you could just randomize based on the ASCII-value range of characters. I'd also suggest using StringBuilder to build the result string.
public class Randomizer{
private static Random rng = new Random();
public static string RandomizeString(string input){
StringBuilder sb = new StringBuilder();
foreach(char c in input){
if(Char.IsNumber(c)){
sb.Append(rng.Next(0,10));
}
else if(Char.IsLower(c)){
sb.Append((char)rng.Next(97,123));
}
else if(Char.IsUpper(c)){
sb.Append((char)rng.Next(65,91));
}
else{
sb.Append(c);
}
}
return sb.ToString();
}
}
Note: a-z is ASCII 97-122, A-Z is ASCII 65-90, and 0-9 is just an integer cast to a string.
This is a little more efficient. I'm not sure about execution time :
private static string GenerateRandomAlphanumericValue(string input)
{
string newStr = "";
string alphaU = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string alphaL = "abcdefghijklmnopqrstuvwxyz";
string number = "0123456789";
Random random = new Random();
for (int i = 0; i < input.Length; i++)
{
if (char.IsNumber(input[i]))
{
int index = random.Next(0, number.Length);
newStr += number[index];
}
else if (char.IsUpper(input[i]))
{
int index = random.Next(0, alphaU.Length);
newStr += alphaU[index];
}
else if (char.IsLower(input[i]))
{
int index = random.Next(0, alphaL.Length);
newStr += alphaL[index];
}
else
{
newStr += input[i];
}
}
return newStr;
}
The general principle is to move as much as possible out of loops and to use the least expensive techniques inside loops.
Random only needs to be constructed once.
StringBuilder is one of the more efficient ways of moving individually acquire Chars into a String. And, it needs to be constructed only once (but introduces thread safety issues).
Array indexing is one fast way to replace chain logic but might not be the fastest since there are only three ranges. (if >= && <= times three could be faster.)
IsUpper et al might have a big impact on its performance. They have to account for all Unicode codepoints in the general category Lu, Ll or Nd.
private static readonly Random random = new Random();
private static readonly StringBuilder sb = new StringBuilder(100);
// min and max are the replacement range for indexing Char.
private static readonly Char[] min = new Char[Char.MaxValue + 1];
private static readonly Char[] max = new Char[Char.MaxValue + 1];
static UserQuery()
{
foreach (var range in new[] {
(min: 'A', max: 'Z'),
(min: 'a', max: 'z'),
(min: '0', max: '9') })
{
for (var c = range.min; c <= range.max; c++)
{
min[c] = range.min;
max[c] = range.max;
}
}
}
private static String GenerateRandomAlphanumericValue(String input)
{
sb.Clear();
foreach (var c in input)
{
sb.Append((Char)random.Next(min[c], max[c]));
}
return sb.ToString();
}
I want to generate a password on the following standard.
One capital letter
10 Small letters
four numbers at the end
Code I have
//Gnerating a random password
string allowedChars = "";
allowedChars = "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,";
allowedChars += "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,";
allowedChars += "1,2,3,4,5,6,7,8,9,0,!,#,#,$,%,&,?";
char[] sep = { ',' };
string[] arr = allowedChars.Split(sep);
string passwordString = "";
string tempString = "";
int PasswordLength = 16;
Random rand = new Random();
for (int i = 0; i < Convert.ToInt32(PasswordLength); i++)
{
tempString = arr[rand.Next(0, arr.Length)];
passwordString += tempString;
}
There is no need to create both an upper and a lower value set. We have code for changing case. You could also extract the actual picking to a separate method, that would make it easier to test.
Here is my attempt:
void Main()
{
char[] lowerCase = new char[] {'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[] numbers = new char[] {'0','1','2','3','4','5','6','7','8','9'};
// Create the Random outside the method to avoid reseeding
Random random = new Random();
// Pick one char and make it uppercase
string password = PickRandomValueFromValueSet(1, lowerCase, random).ToUpper();
// Pick 10 lowercase chars
password+= PickRandomValueFromValueSet(10, lowerCase, random);
// Pick 4 digits
password+= PickRandomValueFromValueSet(4, numbers, random);
Console.Out.WriteLine.(password);
}
string PickRandomValueFromValueSet(int number, char[] valueSet, Random random)
{
string result = "";
for (int i = 0; i < number; i++)
{
result += valueSet[random.Next(0, valueSet.Length)];
}
return result;
}
I don't see why !,#,#,$,%,& and ? were allowed as numbers in the question. I have omitted those.
You need to add different chars to your password string in this way:
string lowerChars = "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,";
string[] lowerCharsArr = lowerChars.Split(sep);
string upperChars = "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,";
string[] upperCharsArr = upperChars.Split(sep);
string numbers = "1,2,3,4,5,6,7,8,9,0";
string[] numbersArr = numbers.Split(sep);
string others = "!,#,#,$,%,&,?";
string[] othersArr = others.Split(sep);
string passwordString = "";
int PasswordLength = 16;
Random rand = new Random();
passwordString += upperChars[rand.Next(0, upperChars.Length)];
for (int i = 1; i < Convert.ToInt32(PasswordLength -4); i++)
{
passwordString += lowerChars[rand.Next(0, lowerChars.Length)];
}
for (int i = 0; i < 4; i++)
{
passwordString += numbersArr[rand.Next(0, numbersArr.Length)];
}
Here's one way you could do this, optionally shuffling the result with the extension method .Shuffle, but if you really want to keep the order of upper first, then lower, then 4 digit/symbols at the end just leave that out.
namespace PasswordGen
{
public class Program
{
private static Random _random = new Random();
static void Main(string[] args)
{
var nonAlphaSymbols = "1234567890!##$%&?";
var password = new[] { (char)_random.Next('A', 'Z' + 1) } // upper case character
.Concat(Enumerable.Range(0, 10).Select(a => (char)_random.Next('a', 'z' + 1)) // 10 lower case
.Concat(Enumerable.Range(0, 4).Select(a => nonAlphaSymbols[_random.Next(0, nonAlphaSymbols.Length)]))) // 4 from nonAlpha
.Shuffle(); // optional, if you want to shuffle the outcome
Console.WriteLine(new string(password.ToArray()));
}
}
public static class Extensions
{
private static Random _random = new Random();
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> input)
{
List<T> output = new List<T>(input);
for (int i = 0; i < output.Count; i++)
{
var swapTarget = _random.Next(i, output.Count - 1);
T temp = output[swapTarget];
output[swapTarget] = output[i];
output[i] = temp;
}
return output;
}
}
}
Example: https://dotnetfiddle.net/BLOEgy
I'm a newbie, shifted from iOS to WP7.
I'm generating a random number series, which I want to store into an array. In iOS it was like this
for(int i=0; i < num; i++) {
int rand = arc4random_uniform(70);
if([rand_array containsObject:[NSNumber numberWithInt:rand]]) {
i--;
}
I've searched, googled but thought this is the place where I can ask a question. Kindly help me.
int min = 1;
int max = 4;
int num = 3;
Random r = new Random();
Int[] ar ;
ar = new Int[num]; // Creates array with 3 palces {ar[0],ar[1],ar[2])
for(i = 0;i =< num - 1;i++) {
ar[i] = r.Next(min,max); // generate random number between 1-4 (include 1 & 4)
}
I think this is should work (or I didnt understand you).
Good luck=]
Enumerable.Range(1, 70) generates numbers from 1 to 70.
Then we shuffle them like a deck of cards.
int[] randomNumbers = Enumerable.Range(1, 70).Shuffle(new Random()).ToArray();
This needs to be in a separate class in the same folder.
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random random)
{
T[] list = source.ToArray();
int count = list.Length;
while (count > 1)
{
int index = random.Next(count--);
yield return list[index];
list[index] = list[count];
}
yield return list[0];
}
Is this what you wanted?
i don't see the sense in your code. I would use a List.
for(int i=0; i < num; i++)
{
int rand = arc4random_uniform(70);//hope you know what you did here, I don't
if(yourList.Contains(rand))
i--;
else
yourList.Add(rand);
}
if the list doesn't contain the random number, it will add it, otherwise it will just repeat.
In C# do something like this:
List<int> numbers = new List<int>();
for ( int i = 0; i < num, i++ ) {
int rand = GetARandomNumber();
if ( !numbers.Contains( rand ) ) {
numbers.Add( rand );
} else {
i--;
}
}
You'd also probably do well to convert this to a while loop:
List<int> numbers = new List<int>();
while ( numbers.Count < num ) {
int rand = GetARandomNumber();
if ( !numbers.Contains( rand ) ) {
numbers.Add( rand );
}
}
It's simple, really! A direct port of your code would look something like:
List<int> rand_array = new List<int>();
for(int i = 0; i < num; i++)
{
int rand = RandomHelper.GetInt(0, 70);
if(rand_array.Contains(rand))
{
i--;
continue;
}
rand_array.Add(rand);
}
To generate random numbers in C# there is a class aptly called "Random". You only really need to use one instance of the Random class to generate numbers, so if you wanted something like this:
static class RandomHelper
{
static Random rng = new Random(); // Seed it if you need the same sequence of random numbers
public static int GetInt(int min, int max)
{
return rng.Next(min, max);
}
}
User enters numbers to 10 textbox and i sent them to an array. Now i want to generate random numbers from this array. What can i do?
Something like this:
public class Randomizer<T>
{
private readonly Random _random = new Random();
private readonly IList<T> _numbers;
public Randomizer(IList<T> numbers)
{
_numbers = numbers;
}
public T Next()
{
int idx = _random.Next(0, _numbers.Count);
return _numbers[idx];
}
}
Usage:
var r = new Randomizer<int>(new int[] { 10, 20, 30, 40, 50 });
for (int i = 0; i < 100; i++)
Console.Write(r.Next() + " ");
Or do you want to shuffle the array?
[Edit]
To shuffle the array, you can use the Fisher–Yates shuffle shown in this post:
// https://stackoverflow.com/questions/108819/110570#110570
public class Shuffler
{
private Random rnd = new Random();
public void Shuffle<T>(IList<T> array)
{
int n = array.Count;
while (n > 1)
{
int k = rnd.Next(n);
n--;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
}
If you want the interface to be same as the Randomizer class above, you can modify it to use the Shuffler class:
public class Randomizer<T>
{
private readonly Shuffler _shuffler = new Shuffler();
private readonly IList<T> _numbers;
public Randomizer(IList<T> numbers)
{
_numbers = new List<T>(numbers);
_shuffler.Shuffle(_numbers);
}
volatile int idx = 0;
public T Next()
{
if (idx >= _numbers.Count)
{
_shuffler.Shuffle(_numbers);
idx = 0;
}
return _numbers[idx++];
}
}
Note that the code is not thread safe, so some locking should be implemented if Next method might be called simultaneously from multiple threads.
Seed the standard System.Random class with a value from the array? If you need your random numbers to depend on ALL array items, then just XOR them all.
public static Random BuildSeededRandom(int[] data)
{
if ( data == null || data.Length < 1 )
return new Random();
int xor = 0;
foreach ( var i in data )
xor ^= i;
return new Random(xor);
}
I need a C# function that takes 2 strings as an input and return an array of all possible combinations of strings.
private string[] FunctionName(string string1, string string2)
{
//code
}
The strings input will be in the following format:
string1: basement
string2: a*fa
Now what I need is all combinations of possible strings using the characters in String2 (ignoring the * symbols), and keeping them in the same character position like this:
baaement, baaefent, baaefena, basefent, basemena, etc.
EDIT:
This is not homework. I need this function for a piece of a program I am doing.
The following is the code I have so far but it has some bugs.
static List<string> combinations = new List<string>();
static void Main(string[] args)
{
//include trimming of input string
string FoundRes = "incoming";
string AltRes = "*2*45*78";
List<int> loc = new List<int>();
string word = "";
for (int i = 0; i < AltRes.Length; i++)
{
if (AltRes[i] != '*')
{
loc.Add(i);
word += AltRes[i];
}
}
generate(word);
string[] aaa = InsertSymbol(FoundRes, loc.ToArray(), AltRes, combinations);
Console.WriteLine("input string: " + FoundRes);
Console.WriteLine("Substitute string: " + AltRes);
Console.WriteLine("============Output============");
for (int j = 0; j < aaa.Length; j++)
{
Console.WriteLine(aaa[j]);
}
Console.ReadKey();
}//
private static void generate(string word)
{
// Add this word to combination results set
if (!combinations.Contains(word))
combinations.Add(word);
// If the word has only one character, break the recursion
if (word.Length == 1)
{
if (!combinations.Contains(word))
combinations.Add(word);
return;
}
// Go through every position of the word
for (int i = 0; i < word.Length; i++)
{
// Remove the character at the current position
// call this method with the String
generate(word.Substring(0, i) + word.Substring(i + 1));
}
}//
private static string[] InsertSymbol(string orig, int[] loc, string alternative, List<string> Chars)
{
List<string> CombinationsList = new List<string>();
string temp = "";
for (int i = 0; i < Chars.Count; i++)
{
temp = orig;
for (int j = 0; j < Chars[i].Length; j++)
{
string token = Chars[i];
if (alternative.IndexOf(token[j]) == loc[j])
{
temp = temp.Remove(loc[j], 1);
temp = temp.Insert(loc[j], token[j].ToString());
// int pos = sourceSubst.IndexOf(token[j]);
// sourceSubst = sourceSubst.Remove(pos, 1);
// sourceSubst = sourceSubst.Insert(pos, ".");
}
else
{
temp = temp.Remove(alternative.IndexOf(token[j]), 1);
temp = temp.Insert(alternative.IndexOf(token[j]), token[j].ToString());
}
}
CombinationsList.Add(temp);
}
return CombinationsList.ToArray();
}//
It does sound like homework. As a suggestion, I would ignore the first parameter and focus on getting all possible permutations of the second string. What's turned off, what's turned on, etc. From that list, you can easily come up with a method of swapping out characters of the first string.
On that note, I'm in the uncomfortable position of having a function ready to go but not wanting to post it because of the homework implication. I'd sure love for somebody to review it, though! And technically, there's two functions involved because I just happened to already have a generic function to generate subsets lying around.
Edit: OP says it isn't homework, so here is what I came up with. It has been refactored a bit since the claim of two functions, and I'm more than open to criticism.
using System;
using System.Collections.Generic;
using System.Text;
class Program
{
static void Main()
{
string original = "phenomenal";
string pattern = "*xo**q*t**";
string[] replacements = StringUtility.GetReplacementStrings(original, pattern, true);
foreach (string replacement in replacements)
Console.WriteLine(replacement);
Console.Read();
}
public static class StringUtility
{
public static string[] GetReplacementStrings(string original, string pattern, bool includeOriginal)
{
// pattern and original might not be same length
int maxIndex = Math.Max(original.Length, pattern.Length);
List<int> positions = GetPatternPositions(pattern, maxIndex, '*');
List<int[]> subsets = ArrayUtility.CreateSubsets(positions.ToArray());
List<string> replacements = GenerateReplacements(original, pattern, subsets);
if (includeOriginal)
replacements.Insert(0, original);
return replacements.ToArray();
}
private static List<string> GenerateReplacements(string original, string pattern, List<int[]> subsets)
{
List<string> replacements = new List<string>();
char[] temp = new char[original.Length];
foreach (int[] subset in subsets)
{
original.CopyTo(0, temp, 0, original.Length);
foreach (int index in subset)
{
temp[index] = pattern[index];
}
replacements.Add(new string(temp));
}
return replacements;
}
private static List<int> GetPatternPositions(string pattern, int maxIndex, char excludeCharacter)
{
List<int> positions = new List<int>();
for (int i = 0; i < maxIndex; i++)
{
if (pattern[i] != excludeCharacter)
positions.Add(i);
}
return positions;
}
}
public static class ArrayUtility
{
public static List<T[]> CreateSubsets<T>(T[] originalArray)
{
List<T[]> subsets = new List<T[]>();
for (int i = 0; i < originalArray.Length; i++)
{
int subsetCount = subsets.Count;
subsets.Add(new T[] { originalArray[i] });
for (int j = 0; j < subsetCount; j++)
{
T[] newSubset = new T[subsets[j].Length + 1];
subsets[j].CopyTo(newSubset, 0);
newSubset[newSubset.Length - 1] = originalArray[i];
subsets.Add(newSubset);
}
}
return subsets;
}
}
}
since it's hopw work I'd only suggest some way to solve the problem rather than writing the code.
if you loop the second parameter every time you hit a letter you'll have to options either use the letter from the first argument or the letter from the second. collect all these optins together with the index. keep a list of the parts from the first argument that will never change. iterate thorugh those two lists to created all the possible permutations
Decimal to Binary converted code is stolon copied from here.
static void Main()
{
string string1 = "basement";
string string2 = "**a*f**a";
string[] result = GetCombinations(string1, string2);
foreach (var item in result)
{
Console.WriteLine(item);
}
}
private static string[] GetCombinations(string string1, string string2)
{
var list = new List<List<char>> { new List<char>(), new List<char>() };
var cl = new List<char>();
List<string> result = new List<string>();
for (int i = 0; i < string1.Length; i++)
{
if (string2[i] == '*')
{
cl.Add(string1[i]);
}
else
{
list[0].Add(string1[i]);
list[1].Add(string2[i]);
}
}
int l = list[0].Count;
for (int i = 0; i < (Int64)Math.Pow(2.0,l); i++)
{
string s = ToBinary(i, l);
string ss = "";
int x = 0;
int y = 0;
for (int I = 0; I < string1.Length; I++)
{
if (string2[I] == '*')
{
ss += cl[x].ToString();
x++;
}
else
{
ss += (list[int.Parse(s[y].ToString())][y]);
y++;
}
}
result.Add(ss);
}
return result.ToArray<string>();
}
public static string ToBinary(Int64 Decimal, int width)
{
Int64 BinaryHolder;
char[] BinaryArray;
string BinaryResult = "";
while (Decimal > 0)
{
BinaryHolder = Decimal % 2;
BinaryResult += BinaryHolder;
Decimal = Decimal / 2;
}
BinaryArray = BinaryResult.ToCharArray();
Array.Reverse(BinaryArray);
BinaryResult = new string(BinaryArray);
var d = width - BinaryResult.Length;
if (d != 0) for (int i = 0; i < d; i++) BinaryResult = "0" + BinaryResult;
return BinaryResult;
}
which password cracker do you want to program? :)
how about
if string2 contains '*'
foreach(char ch in string1)
replace first * with ch,
execute FunctionName
else
print string2