| 

.NET C# Java Javascript Exception

3
Wie kann ich Zufallszeichenketten (Datentyp String) generieren lassen und die dafür zulässigen Zeichen frei vordefinieren?
08.03.2011
Pal01 31 1 2
5 Antworten
6
RandomString erzeugen:
public static string RandomString(int maxSize)
{
char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray();
byte[] data = new byte[1];
RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider();
crypto.GetNonZeroBytes(data);
data = new byte[maxSize];
crypto.GetNonZeroBytes(data);
StringBuilder result = new StringBuilder(maxSize);
foreach (byte b in data)
{
result.Append(chars[b % (chars.Length - 1)]);
}
return result.ToString();
}

Aufruf:
static void Main(string[] args)
{
string randomString = RandomString(14);
Console.WriteLine(randomString);
}


Nachtrag: Ich habe gerade gesehen, dass es auch für VB.NET sein soll. Der C# -> VB.NET-Konverter spuckt das hier aus:
Dim chars As Char() = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".ToCharArray()
Dim data As Byte() = New Byte(0) {}
Dim crypto As New RNGCryptoServiceProvider()
crypto.GetNonZeroBytes(data)
data = New Byte(maxSize - 1) {}
crypto.GetNonZeroBytes(data)
Dim result As New StringBuilder(maxSize)
For Each b As Byte In data
result.Append(chars(b Mod (chars.Length - 1)))
Next
Return result.ToString()
08.03.2011
Jürgen Luhr 7,1k 1 9
3
Hi,

zum Beispiel so:

public class RandomText
{
private string _allowedChars = "abcdefghijklmnopqrstuvwxyz";

public string GenerateRandomText(int numberOfChars)
{
string result = String.Empty;
char[] chars = _allowedChars.ToCharArray();

Random rnd = new Random();
for (int i = 0; i < numberOfChars; i++)
{
int nextIndex = rnd.Next(0, chars.Length - 1);
result += chars[nextIndex].ToString();
}

return result;
}
}
08.03.2011
ThomasEParis 155 5
1
Besonders zufällig ist der Zufallstext aber nicht.
Diese Aufrufe hintereinander liefern immer den gleichen Text:
string randomString = GenerateRandomText(14);
Console.WriteLine(randomString);
string randomString2 = GenerateRandomText(14);
Console.WriteLine(randomString2);
string randomString3 = GenerateRandomText(14);
Console.WriteLine(randomString3);

Siehe dazu auch:
http://codekicker.de/fragen/Wie-zufaellig-ist-Random-in-net/225
Jürgen Luhr 08.03.2011
1
ja weil ja die klasse zur erzeugung immer eine neue instanz von Random erzeugt, das gehört natürlich in den konstruktor, und über die lebenszeit der klasse nicht neu instanziiert.

nabuchodonossor 08.03.2011
Schon klar, soll ja auch nur als Beispiel dienen, wie man das umsetzen könnte. Um es zufälliger zu machen, kann man ja den 2. Konstruktor von Random beschicken, z.B. mit den Millisekunden seit Mitternacht - oder was immer einem dazu einfällt.
ThomasEParis 08.03.2011
vermutlich wollte ThomasEParis den Pal01 nur testen *g*
nabuchodonossor 08.03.2011
Na, ein wenig mitdenken muss schon drin sein ;-)
ThomasEParis 08.03.2011
@Jürgen: aber du hast schon recht, mit dem Krypto-Provider ist das Zufallsmuster deutlich besser. Ich dachte mir bei dieser Anforderung, dass es hier vermutlich um Testdatengenerierung geht und da sollte dieser Ansatz völlig ausreichend sein.
ThomasEParis 08.03.2011
3
Ich bin ja normalerweise nicht der Fan von "zuviel Sourcecode für andere" schreiben, aber weil mich ThomasEParis auf eine gute Idee gebracht hat:

public static class StringExtensions
{
static Random _myRandom;
static char[] _myRandomAllowedChars;

public static void RandomTextInitializer(this string value)
{
_myRandom = new Random();
_myRandomAllowedChars = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
}

public static void RandomTextInitializer(this string value, string AllowedChars)
{
_myRandom = new Random();
_myRandomAllowedChars = AllowedChars.ToCharArray();
}

public static void RandomTextInitializer(this string value, char[] AllowedChars)
{
_myRandom = new Random();
_myRandomAllowedChars = AllowedChars;
}

public static void RandomTextInitializer(this string value, string AllowedChars, Random Randomizer)
{
_myRandom = Randomizer;
_myRandomAllowedChars = AllowedChars.ToCharArray();
}

public static void RandomTextInitializer(this string value, char[] AllowedChars, Random Randomizer)
{
_myRandom = Randomizer;
_myRandomAllowedChars = AllowedChars;
}

public static string RandomTextGenerator(this string value, int numberOfChars)
{
string result = String.Empty;

for (int i = 0; i < numberOfChars; i++)
{
int nextIndex = _myRandom.Next(0, _myRandomAllowedChars.Length - 1);
result += _myRandomAllowedChars[nextIndex].ToString();
}

return result;
}

}


Die Verwendung ist dann sehr einfach:

string irgendwas = "";

irgendwas.RandomTextInitializer("abcdefg", new Random((int)DateTime.Now.Ticks));

MessageBox.Show(irgendwas.RandomTextGenerator(13));
MessageBox.Show(irgendwas.RandomTextGenerator(2));


Ja, und ich weiss, dass ich die "nextIndex" int nicht bräuchte, das ginge inline auch:

result += _myRandomAllowedChars[_myRandom.Next(0, _myRandomAllowedChars.Length - 1)].ToString();
08.03.2011
nabuchodonossor 1,3k 5
2
Das ist auch ein netter Ansatz. Allerdings hätte ich es schon besser gefunden, wenn du, natürlich von außen parametrierbar, auch alternativ Jürgens' Ansatz in die Klasse hättest einfließen lassen ;-)
ThomasEParis 08.03.2011
Mal schauen ... vielleicht find ich dazu auch noch Zeit.
nabuchodonossor 08.03.2011
1
Der Ansatz ist nicht schlecht und zeigt von kreativität. Mir persönlich gefällt er aber nicht da man bei diesem Ansatz die String-Extensions für eine selten genutze Sache missbraucht. Die zweite, in meinen größere, Unschönheit ist das ich 2 String-Extensions brauche und diese für jeden String aufrufen muss. Trotzdem +1 von mir!
Floyd 08.03.2011
Danke für Blumen und guten Hinweis. Wegen 2 Methoden: Nein, man muss nicht für jeden String 2 aufrufen, der erste initialisert den Generator, und solange diese Instanz verfügbar ist, bleibt der Zeichensatz (oder alles andere was man vielleicht parametrisieren möchte, z.B. Cryptogenerator) erhalten, und es wird nur mehr abgerufen. Aber natürlich wäre eine dynamische Klasse, die ich bei Bedarf instanziiere schöner als eine String Extension.
nabuchodonossor 09.03.2011
2
So, für alle, die hier nicht Ansätze sondern komplette Lösungen sehen wollen (weil sie zu faul zum Programmieren sind? ;-) ):

public class RandomText
{
private string _allowedChars = "abcdefghijklmnopqrstuvwxyz";
private Random _rnd = new Random((int)DateTime.Now.Ticks);

public string GenerateRandomText(int numberOfChars)
{
string result = String.Empty;
char[] chars = _allowedChars.ToCharArray();

for (int i = 0; i < numberOfChars; i++)
{
int nextIndex = _rnd.Next(0, chars.Length - 1);
result += chars[nextIndex].ToString();
}

return result;
}
}
08.03.2011
ThomasEParis 155 5
1
Ich hab schon noch was zu meckern: Ganz fertig ist es noch nicht: Konstruktor mit "erlaubtem Zeichensatz" wäre noch schön *g*
nabuchodonossor 08.03.2011
2
Alter Schwede - ich bin ja kein Tell-Me-What-You-Want-And-You-Get-It-ASAP-And-For-Nuts-Unternehmen *ggg*
ThomasEParis 08.03.2011
das ist der grund, warum ich meinen zufallsdatengenerator für alles mögliche nicht reinstellen werde. ein bisserl was muss der jeweils fragende auch selber lösen. aber gscheit reden ist natürlich einfach hehe
nabuchodonossor 08.03.2011
0
Is vllt nicht die beste Lösung aber schonmal ein Anfang ^^

Dim MyList As New ArrayList
Dim MyString As String = ""
Dim AnzahlDerZeichen As Integer

MyList.Add("a")
MyList.Add("b")
MyList.Add("%")

For i As Integer = 0 To AnzahlDerZeichen
MyString &= MyList.Item(Rnd() * (MyList.Count - 1))
Next
08.03.2011
DerPunk 1,2k 1 7

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH