Ich möchte zufällige eindeutige Zeichenfolgen generieren, wie sie beispielsweise von der MSDN-Bibliothek ( Fehlerobjekt ) generiert werden . Ein String wie 't9zk6eay' sollte generiert werden.
Ich möchte zufällige eindeutige Zeichenfolgen generieren, wie sie beispielsweise von der MSDN-Bibliothek ( Fehlerobjekt ) generiert werden . Ein String wie 't9zk6eay' sollte generiert werden.
Antworten:
Die Verwendung von Guid wäre ein ziemlich guter Weg, aber um etwas zu erhalten, das Ihrem Beispiel ähnelt, möchten Sie es wahrscheinlich in eine Base64-Zeichenfolge konvertieren:
Guid g = Guid.NewGuid();
string GuidString = Convert.ToBase64String(g.ToByteArray());
GuidString = GuidString.Replace("=","");
GuidString = GuidString.Replace("+","");
Ich werde "=" und "+" los, um Ihrem Beispiel ein wenig näher zu kommen, andernfalls erhalten Sie "==" am Ende Ihrer Zeichenfolge und ein "+" in der Mitte. Hier ist ein Beispiel für eine Ausgabezeichenfolge:
"OZVV5TpP4U6wJthaCORZEQ"
Convert.ToBase64String
geht, finden Sie hier .
new Guid()
ohne "Hacking" (Manipulation der Uhr oder interner Windows-Datenstrukturen) Kollisionen verursacht . Sie können beliebig viele Kerne, Threads, Synchronisationsprimitive usw. verwenden.
Update 23.01.2016
Wenn Sie diese Antwort nützlich finden, interessieren Sie sich möglicherweise für eine einfache (~ 500 SLOC) Kennwortgenerierungsbibliothek, die ich veröffentlicht habe :
Install-Package MlkPwgen
Dann können Sie zufällige Zeichenfolgen wie in der folgenden Antwort generieren:
var str = PasswordGenerator.Generate(length: 10, allowed: Sets.Alphanumerics);
Ein Vorteil der Bibliothek besteht darin, dass der Code besser herausgerechnet wird, sodass Sie sichere Zufälligkeit für mehr als das Generieren von Zeichenfolgen verwenden können . Schauen Sie sich die Projektseite anWeitere Informationen finden .
Da noch niemand sicheren Code bereitgestellt hat, poste ich Folgendes, falls jemand es nützlich findet.
string RandomString(int length, string allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") {
if (length < 0) throw new ArgumentOutOfRangeException("length", "length cannot be less than zero.");
if (string.IsNullOrEmpty(allowedChars)) throw new ArgumentException("allowedChars may not be empty.");
const int byteSize = 0x100;
var allowedCharSet = new HashSet<char>(allowedChars).ToArray();
if (byteSize < allowedCharSet.Length) throw new ArgumentException(String.Format("allowedChars may contain no more than {0} characters.", byteSize));
// Guid.NewGuid and System.Random are not particularly random. By using a
// cryptographically-secure random number generator, the caller is always
// protected, regardless of use.
using (var rng = System.Security.Cryptography.RandomNumberGenerator.Create()) {
var result = new StringBuilder();
var buf = new byte[128];
while (result.Length < length) {
rng.GetBytes(buf);
for (var i = 0; i < buf.Length && result.Length < length; ++i) {
// Divide the byte into allowedCharSet-sized groups. If the
// random value falls into the last group and the last group is
// too small to choose from the entire allowedCharSet, ignore
// the value in order to avoid biasing the result.
var outOfRangeStart = byteSize - (byteSize % allowedCharSet.Length);
if (outOfRangeStart <= buf[i]) continue;
result.Append(allowedCharSet[buf[i] % allowedCharSet.Length]);
}
}
return result.ToString();
}
}
Vielen Dank an Ahmad für den Hinweis, wie der Code auf .NET Core funktioniert.
.netcore
: Ersetzen var rng = new RNGCryptoServiceProvider()
durchvar rng = RandomNumberGenerator.Create()
Ich würde darauf hinweisen, dass GUIDs keine Zufallszahlen sind . Sie sollten nicht als Grundlage verwendet werden, um etwas zu generieren, von dem Sie erwarten, dass es völlig zufällig ist (siehe http://en.wikipedia.org/wiki/Globally_Unique_Identifier ):
Die Kryptoanalyse des WinAPI-GUID-Generators zeigt, dass man, da die Folge von V4-GUIDs pseudozufällig ist, angesichts des Anfangszustands bis zu 250.000 GUIDs vorhersagen kann, die von der Funktion UuidCreate zurückgegeben werden. Aus diesem Grund sollten GUIDs in der Kryptografie nicht verwendet werden, z. B. als Zufallsschlüssel.
Verwenden Sie stattdessen einfach die C # Random-Methode. So etwas ( Code hier gefunden ):
private string RandomString(int size)
{
StringBuilder builder = new StringBuilder();
Random random = new Random();
char ch ;
for(int i=0; i<size; i++)
{
ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65))) ;
builder.Append(ch);
}
return builder.ToString();
}
GUIDs sind in Ordnung, wenn Sie etwas Einzigartiges möchten (wie einen eindeutigen Dateinamen oder Schlüssel in einer Datenbank), aber sie sind nicht gut für etwas, das Sie zufällig sein möchten (wie ein Kennwort oder ein Verschlüsselungsschlüssel). Das hängt also von Ihrer Anwendung ab.
Bearbeiten . Microsoft sagt, dass Random auch nicht so toll ist ( http://msdn.microsoft.com/en-us/library/system.random(VS.71).aspx ):
Verwenden Sie zum Generieren einer kryptografisch sicheren Zufallszahl, die zum Erstellen eines zufälligen Kennworts geeignet ist, beispielsweise eine von System.Security.Cryptography.RandomNumberGenerator abgeleitete Klasse, z. B. System.Security.Cryptography.RNGCryptoServiceProvider.
Ich habe die @ Michael Kropats-Lösung vereinfacht und eine LINQ-ähnliche Version erstellt.
string RandomString(int length, string alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
{
var outOfRange = byte.MaxValue + 1 - (byte.MaxValue + 1) % alphabet.Length;
return string.Concat(
Enumerable
.Repeat(0, int.MaxValue)
.Select(e => RandomByte())
.Where(randomByte => randomByte < outOfRange)
.Take(length)
.Select(randomByte => alphabet[randomByte % alphabet.Length])
);
}
byte RandomByte()
{
using (var randomizationProvider = new RNGCryptoServiceProvider())
{
var randomBytes = new byte[1];
randomizationProvider.GetBytes(randomBytes);
return randomBytes.Single();
}
}
Ich denke nicht, dass sie wirklich zufällig sind, aber ich vermute, das sind einige Hashes.
Wenn ich eine zufällige Kennung benötige, verwende ich normalerweise eine GUID und konvertiere sie in ihre "nackte" Darstellung:
Guid.NewGuid().ToString("n");
Ich bin überrascht, warum es keine CrytpoGraphic-Lösung gibt. Die GUID ist eindeutig, aber nicht kryptografisch sicher . Siehe diese Dotnet-Geige.
var bytes = new byte[40]; // byte size
using (var crypto = new RNGCryptoServiceProvider())
crypto.GetBytes(bytes);
var base64 = Convert.ToBase64String(bytes);
Console.WriteLine(base64);
Falls Sie mit einem Guid voranstellen möchten:
var result = Guid.NewGuid().ToString("N") + base64;
Console.WriteLine(result);
Eine sauberere alphanumerische Zeichenfolge:
result = Regex.Replace(result,"[^A-Za-z0-9]","");
Console.WriteLine(result);
Michael Kropats Lösung in VB.net
Private Function RandomString(ByVal length As Integer, Optional ByVal allowedChars As String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") As String
If length < 0 Then Throw New ArgumentOutOfRangeException("length", "length cannot be less than zero.")
If String.IsNullOrEmpty(allowedChars) Then Throw New ArgumentException("allowedChars may not be empty.")
Dim byteSize As Integer = 256
Dim hash As HashSet(Of Char) = New HashSet(Of Char)(allowedChars)
'Dim hash As HashSet(Of String) = New HashSet(Of String)(allowedChars)
Dim allowedCharSet() = hash.ToArray
If byteSize < allowedCharSet.Length Then Throw New ArgumentException(String.Format("allowedChars may contain no more than {0} characters.", byteSize))
' Guid.NewGuid and System.Random are not particularly random. By using a
' cryptographically-secure random number generator, the caller is always
' protected, regardless of use.
Dim rng = New System.Security.Cryptography.RNGCryptoServiceProvider()
Dim result = New System.Text.StringBuilder()
Dim buf = New Byte(128) {}
While result.Length < length
rng.GetBytes(buf)
Dim i
For i = 0 To buf.Length - 1 Step +1
If result.Length >= length Then Exit For
' Divide the byte into allowedCharSet-sized groups. If the
' random value falls into the last group and the last group is
' too small to choose from the entire allowedCharSet, ignore
' the value in order to avoid biasing the result.
Dim outOfRangeStart = byteSize - (byteSize Mod allowedCharSet.Length)
If outOfRangeStart <= buf(i) Then
Continue For
End If
result.Append(allowedCharSet(buf(i) Mod allowedCharSet.Length))
Next
End While
Return result.ToString()
End Function
Dies wurde für verschiedene Sprachen gefragt. Hier ist eine Frage zu Passwörtern die auch hier gelten sollte.
Wenn Sie die Zeichenfolgen für die URL-Verkürzung verwenden möchten, benötigen Sie außerdem ein Wörterbuch <> oder eine Datenbankprüfung, um festzustellen, ob bereits eine generierte ID verwendet wurde.
Wenn Sie eine alphanumerische Zeichenfolge mit Kleinbuchstaben und möchten Großbuchstaben ([a-zA-Z0-9]) möchten, können Sie Convert.ToBase64String () für eine schnelle und einfache Lösung verwenden.
Überprüfen Sie hinsichtlich der Eindeutigkeit das Geburtstagsproblem, um zu berechnen, wie wahrscheinlich eine Kollision ist (A) die Länge der generierten Zeichenfolgen und (B) die Anzahl der generierten Zeichenfolgen.
Random random = new Random();
int outputLength = 10;
int byteLength = (int)Math.Ceiling(3f / 4f * outputLength); // Base64 uses 4 characters for every 3 bytes of data; so in random bytes we need only 3/4 of the desired length
byte[] randomBytes = new byte[byteLength];
string output;
do
{
random.NextBytes(randomBytes); // Fill bytes with random data
output = Convert.ToBase64String(randomBytes); // Convert to base64
output = output.Substring(0, outputLength); // Truncate any superfluous characters and/or padding
} while (output.Contains('/') || output.Contains('+')); // Repeat if we contain non-alphanumeric characters (~25% chance if length=10; ~50% chance if length=20; ~35% chance if length=32)
Holen Sie sich den eindeutigen Schlüssel mithilfe des GUID-Hash-Codes
public static string GetUniqueKey(int length)
{
string guidResult = string.Empty;
while (guidResult.Length < length)
{
// Get the GUID.
guidResult += Guid.NewGuid().ToString().GetHashCode().ToString("x");
}
// Make sure length is valid.
if (length <= 0 || length > guidResult.Length)
throw new ArgumentException("Length must be between 1 and " + guidResult.Length);
// Return the first length bytes.
return guidResult.Substring(0, length);
}
string randoms = Guid.NewGuid().ToString().Replace("-", string.Empty).Replace("+", string.Empty).Substring(0, 4);
mehr finden Sie hier