Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Key Generator
Björn
myCSharp.de - Member



Dabei seit:
Beiträge: 153
Herkunft: Rhode

Themenstarter:

Key Generator

beantworten | zitieren | melden

Hallo zusammen,

ich habe zu Übungszwecke mal einen kleinen Keygenerator geschrieben, welcher euch Keys erstellt und auch überprüft. Ich stelle ihn hier zur Verfügung, vielleicht kann ihn ja jemand gebrauchen oder hat noch ein paar Verbesserungsvorschläge

Beschreibung:

Ein simpler Keygenerator, welcher Schlüssel erstellt überprüft.
Je nach Einstellung hat der Schlüssel zum Beispiel so ein aussehen:

"cfhSL-NNnNS-dPyjn-Z6vlG-1SMbV"



Folgende Einstellungen könnt ihr machen:


        /// <summary>
        /// Legt die Anzahl der Schlüsselelemente fest. Muss größer oder gleich 2 sein.
        /// </summary>
        public int numberOfKeyElements
        {
              // 5
        }

        /// <summary>
        /// Setzt die Anzahl der Zeichen pro Schlüsselelement oder gibt diese zurück! Muss größer oder gleich 3 sein!
        /// </summary>
        public int KeyLengthPE
        {
              // 5
        }


        /// <summary>
        /// Setzt oder gibt das Trennzeichen für die Schlüsselelemente zurück. Das Trennzeichen darf nicht in den verwendbaren Zeichen für den Schlüssel vorkommen!
        /// </summary>
        public char KeySeperator
        {
              // -
        }

        /// <summary>
        ///  Setzt oder gibt den Schlüsseltypen zurück.
        /// </summary>
        public KeyTyp Keytyp
        {
              // KeyTyp.AlphaNumeric (also Zahlen und Buchstaben String)
              // Möglich sind noch Numeric (nur Zahlenstring) und Alpha (nur Buchstabenstring)
        }

        /// <summary>
        /// Legt die validen Buchstaben für den Schlüssel fest.
        /// </summary>
        public string ValidAlphaKeys
        {
              // ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
        }

        /// <summary>
        /// Legt die validen numerischen Zeichen für den Schlüssel fest.
        /// </summary>
        public string ValidNumericKeys
        {
             // 0123456789
        }

        /// <summary>
        /// Legt fest oder gibt an, ob die Groß- / Kleinschreibung beachtet wird.
        /// </summary>
        public bool UseCaseSensitive
        {
             // true
        }

Dies sind die Einstellungsmöglichkeiten. Die Kommentare geben die Standardwerte wieder. Nun noch kurz zu den Erstellen / Prüfen funktionen.

        /// <summary>
        /// Erstellt einen Schlüssel.
        /// </summary>
        /// <returns>Gibt einen Schlüssel als String zurück, getrennt durch den Seperator.</returns>
        public string GenerateKey()
        {
        }

        /// <summary>
        /// Erstellt einen Schlüssel.
        /// </summary>
        /// <returns>Gibt einen Schlüssel als Array zurück.</returns>
        public string[] GenerateKeyAr()
        {
        }

        /// <summary>
        /// Prüft einen Schlüssel, welcher anhand des "KeySeperator" aufgesplittet wird.
        /// </summary>
        /// <param name="Key">Der Schlüssel als kompletter String</param>
        /// <returns>true wenn der Schlüssel valid ist, false wenn nicht.</returns>
        public bool CheckKey(string Key)
        {
        }

        /// <summary>
        /// Prüft einen Schlüssel anhand der einzelnen Elemente.
        /// </summary>
        /// <param name="KeyElements">Array mit den einzelnen Schlüsselelementen</param>
        /// <returns>true wenn der Schlüssel valid ist, false wenn nicht.</returns>
        public bool CheckKey(string[] KeyElements)
        {
        }

Denke die Erklärungen sind selbst sprechend!

Im Anhang findet ihr eine kompilierte DLL sowie den Source Code.
Wünsche viel Spaß damit und ich dankbar für eure Kommentare

Ach ja noch kurz, der "Algorithmus" ist was selbst ausgedachtes und sicherlich nichts wirklich sicheres aber ich denke für kleinere Dinge sollte er ausreichen.

MfG Björn

Schlagwörter: Key, Gen, Keygenerator, Generator, Schlüssel, Serial
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von Björn am .
Attachments
private Nachricht | Beiträge des Benutzers
ikaros
myCSharp.de - Member



Dabei seit:
Beiträge: 1787

beantworten | zitieren | melden

Frage:
Was wäre denn der Anwendungszweck, z.B. im Vergleich zu einer GUID?
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo ikaros,
Zitat
Was wäre denn der Anwendungszweck, z.B. im Vergleich zu einer GUID?
z.B. CD-Keys oder Keys für Shareware. Der Vorteil gegenüber einer GUID ist, dass man Länge und Aufbau des Keys an die eigenen Vorstellungen anpassen kann.

herbivore
private Nachricht | Beiträge des Benutzers
ikaros
myCSharp.de - Member



Dabei seit:
Beiträge: 1787

beantworten | zitieren | melden

Danke,
daran hatte ich nicht gedacht.
private Nachricht | Beiträge des Benutzers
handycommander
myCSharp.de - Member

Avatar #avatar-2487.gif


Dabei seit:
Beiträge: 422

beantworten | zitieren | melden

Also ich hab mir das ganze mal eben angesehen und ausprobiert.
Jedoch krieg ich immer die Meldung, dass der eingegebene Schlüssel nicht richtig ist, obwohl ich mit einem Button den Key erzeuge und in eine TextBox speichere und in mit einem anderen Button prüfe, ob er gültig ist.

Hier mal mein Code, mit dem ich getestet habe:


        private void button2_Click(object sender, EventArgs e)
        {
            KeyGen kg = new KeyGen();
            kg.KeySeperator = '-';
            kg.KeyLengthPE = 5;
            kg.Keytyp = KeyTyp.AlphaNumeric;
            kg.numberOfKeyElements = 4;
            kg.UseCaseSensitive = true;
            MessageBox.Show(kg.CheckKey(textBox1.Text).ToString());
        }

        private void button1_Click(object sender, EventArgs e)
        {
            KeyGen kg1 = new KeyGen();
            kg1.KeySeperator = '-';
            kg1.KeyLengthPE = 5;
            kg1.Keytyp = KeyTyp.AlphaNumeric;
            kg1.numberOfKeyElements = 4;
            kg1.UseCaseSensitive = true;
            textBox1.Text = kg1.GenerateKey();
        }

Mfg Tobi
private Nachricht | Beiträge des Benutzers
handycommander
myCSharp.de - Member

Avatar #avatar-2487.gif


Dabei seit:
Beiträge: 422

beantworten | zitieren | melden

ok, ich hab den Fehler gefunden.
In der Methode "checkKey" muss einfach folgendes abgeändert werden:


            for (int i = 0; i < this.lNumberOfKeyElements; i++)
            {
                if (this.lUseCaseSensitive)
                {
                    // Wenn groß und kleinschreibung nicht beachtet werden soll!
                    KeyElements[i] = KeyElements[i].ToUpper();
                }
                if (this.lKeyElements[i] != KeyElements[i])
                {
                    return false;
                }
            }

zu:


            for (int i = 0; i < this.lNumberOfKeyElements; i++)
            {
                if (this.lUseCaseSensitive)
                {
                    // Wenn groß und kleinschreibung nicht beachtet werden soll!
                    KeyElements[i] = KeyElements[i].ToUpper();
                    this.lKeyElements[i] = this.lKeyElements[i].ToUpper();
                }
                if (this.lKeyElements[i] != KeyElements[i])
                {
                    return false;
                }
            }

Mfg Tobi
private Nachricht | Beiträge des Benutzers
Joetempes
myCSharp.de - Member

Avatar #avatar-3309.jpg


Dabei seit:
Beiträge: 914
Herkunft: Germany

beantworten | zitieren | melden

Der KeyGen funktioniert nicht beim Wechsel von x86 zu x64 oder umgedreht.
(Also auch nicht beim Wechsel von Windows XP zu z.B. W7)

Der Grund dafür ist das string.GetHashCode() unterschiedliche Werte für den gleichen String bei unterschiedlicher Prozessorarchitektur liefert.

Lösungen aus dem Netz:


    /// <summary>
    /// Similar to String.GetHashCode but returns the same as the x86 version of String.GetHashCode for x64 and x86 frameworks.
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static unsafe int GetHashCode32(string s)
    {
        fixed (char* str = s.ToCharArray())
        {
            char* chPtr = str;
            int num = 0x15051505;
            int num2 = num;
            int* numPtr = (int*)chPtr;
            for (int i = s.Length; i > 0; i -= 4)
            {
                num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
                if (i ≤ 2)
                {
                    break;
                }
                num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
                numPtr += 2;
            }
            return (num + (num2 * 0x5d588b65));
        }
    }

oder


/// <summary>
/// http://www.codeproject.com/Articles/34309/Convert-String-to-64bit-Integer
/// Return unique Int64 value for input string
/// </summary>
/// <param name="strText"></param>
/// <returns></returns>
static Int64 GetInt64HashCode(string strText)
{
    Int64 hashCode = 0;
    if (!string.IsNullOrEmpty(strText))
    {
        //Unicode Encode Covering all characterset
          byte[] byteContents = Encoding.Unicode.GetBytes(strText);
        System.Security.Cryptography.SHA256 hash = 
		new System.Security.Cryptography.SHA256CryptoServiceProvider();
        byte[] hashText = hash.ComputeHash(byteContents);
        //32Byte hashText separate
        //hashCodeStart = 0~7  8Byte
        //hashCodeMedium = 8~23  8Byte
        //hashCodeEnd = 24~31  8Byte
        //and Fold
        Int64 hashCodeStart = BitConverter.ToInt64(hashText, 0);
        Int64 hashCodeMedium = BitConverter.ToInt64(hashText, 8);
        Int64 hashCodeEnd = BitConverter.ToInt64(hashText, 24);
        hashCode = hashCodeStart ^ hashCodeMedium ^ hashCodeEnd;
    }
    return (hashCode);
}        
private Nachricht | Beiträge des Benutzers
Grimmbizkit
myCSharp.de - Member



Dabei seit:
Beiträge: 310
Herkunft: Niederrhein

beantworten | zitieren | melden

Hallo,

ich finde diese Klasse echt super.
Allerdings habe ich eine kleine Anregung bzw Frage.

Ich würde gerne einen String mit für die Generierung hinzuziehen.

Als Beispiel den PC-Name.

Ist sowas möglich und wie?

Gruß Simon
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Grimmbizkit,

es steht dir doch frei, die Methode GenerateKey mit einem String-Parameter auszustatten, den du intern bis an die Stelle(n) weitergibst, wo die Zufallswerte erzeugt werden, um dort den Inhalt des Strings in der von dir gewünschten Weise in das Ergebnis der Erzeugung einfließen zu lassen. Deine Änderungen/Überarbeitungen kannst du dann gerne für die Nachwelt in diesem Thread posten.

herbivore
private Nachricht | Beiträge des Benutzers
Grimmbizkit
myCSharp.de - Member



Dabei seit:
Beiträge: 310
Herkunft: Niederrhein

beantworten | zitieren | melden

Danke herbivore,

aber ich möchte diesen String auch bei CheckKey nutzen, als zusätzliche Kontrolle.

Da finde ich irgendwie nicht den Ansatz.

Gruß Simon
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Grimmbizkit,

dafür gibt es verschiedene Möglichkeiten.

Du könntest als Seed für die Generierung von Zufallszahlen den Hashcode des Strings (z.B. PC-Name) verwenden (beachte dazu allerdings, was Joetempes bezüglich der Hashberechnung geschrieben hat). Dadurch wäre der Seed deterministisch und ein erneutes Aufrufen von GenerateKey mit dem gleichen String würde dasselbe Ergebnis liefern. Du könntest also in CheckKey, das dafür ebenfalls einen (weiteren) String-Parameter bekommen müsste, einfach nochmal GenerateKey aufrufen und schauen, um das Ergebnis mit dem zu prüfenden String übereinstimmt.

Natürlich kannst du den String auch nur in einen Teil des Keys einfließen lassen und den Rest zufällig wie bisher halten.

Statt Hashcode des Strings als Seed zu verwenden, könntest du auch (mehrfach) die MD5-Summe (o.ä.) berechnen und Teile daraus aus Teile des Keys verwenden. Auch hier wäre die Berechnung deterministisch und würde sich nachträglich prüfen lassen.

Das nur als Anregung. Bei der konkrete Ausgestaltung bist du frei. Und es gibt natürlich noch weitere Möglichkeiten und Varianten.

herbivore
private Nachricht | Beiträge des Benutzers
Grimmbizkit
myCSharp.de - Member



Dabei seit:
Beiträge: 310
Herkunft: Niederrhein

beantworten | zitieren | melden

Morgen Zusammen,

ich habe den PC-Namen einfach mit an die "toShuffle" angefügt.
Gebe ich diesen String auch mit beim CheckKey an ist alles ok.

Nun habe ich aber noch ein kleines Problem.

Ich würde gerne eine Zahl (Lizenzgröße) mit in den Key packen und diesen später auch wieder auslesen. Kann ich überhaupt Werte später wieder auslesen?

Gruß Simon
private Nachricht | Beiträge des Benutzers
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

beantworten | zitieren | melden

Hallo Grimmbizkit,

natürlich kannst du bestimmte Stellen des Keys verwenden, um darin (verschlüsselt aber trotzdem) wieder auslesbare Informationen zu speichern.

Wenn es jedoch nur wenige verschiedene Lizenzgrößen gibt, dann könntest du probieren die Lizenzgröße einfach ebenfalls an toShuffle anhängen. Beim Prüfen gehst du dann einfach alle Möglichkeiten durch, und schaust bei welcher die Prüfung erfolgreich ist. Das klappt natürlich nur dann zuverlässig, wenn alle Zeichen von toShuffle komplett in den Key einfließen.

herbivore
private Nachricht | Beiträge des Benutzers