Click here to Skip to main content
15,905,419 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
So i'm back with a new question.

I am currently developing a name & password generator because I always seem to have a issue with coming up with names & once I do I never save them.
I will have it as my main project that I work on when im not doing any other projects.

This is the basic idea

1).You press a button & it generates random string (a name & password.)
2). If you dont like that name & password you can press a new button to generate a new one.
2).If you are happy with the outcome you can press another button to save it as a txt file.

That is the basic idea.
As mentioned earlier in the question I will have it as a main project so I will work on it & try to eventually be able to add an encryption to the password to probably a 2048 bit one.

--ISSUE--

So, to get me started I would need some help, with some sort of "Code snippet if that is possible" I seem to have a small issue creating the random string generator itself, I tried googleing for examples but I only found really complex ones, I know there should be as easy way creating it with like a string such as

C#
string rString = ("abcdefghijklmnopqrstuvwxyz");

and then.. and this is where my brain shuts off, If anyone could help me. Keep in mind im not asking you to write me the code, I would love a code snippet or some links to where I can learn this stuff.

Thanks!
Posted
Comments
BillWoodruff 29-Dec-15 19:12pm    
You need to make some decisions about the allowable range of Characters: do you allow upper- and lower- case, digits, and punctuation marks ... if punctuation marks, which ones ?

Various applications, and web-sites, vary quite a bit in allowable formats. Adobe, for example, requires a password that starts with an upper-case letter for PhotoShop CS. Some apps demand at least one number, and, of course, number of allowed characters vary.

I'd like to see you start writing some code.
BladeLogan 29-Dec-15 19:19pm    
Well.. This is what I got so far.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication14
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

char[] letters = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
Random r = new Random();
string randomString = "";



private void button1_Click(object sender, EventArgs e)
{
textBox1.Text = randomString;
for (int i = 0; i < 10; i++)

{
randomString += letters[r.Next(0, 26)].ToString() ;


}
}

}
}
BladeLogan 29-Dec-15 19:20pm    
Its working perfectly, now I need to tweak it be be better, like not stack directly after each other etc, like make a list in the text box.
BillWoodruff 30-Dec-15 7:27am    
I believe you'll get the best responses if you take the code posted here as a comment and move it into your original post, formatting it using the CP Editor.
BladeLogan 29-Dec-15 19:21pm    
& When I say simple, I mean like basic stuff, as you caan see, The way im learning is by making something REALLY simple & thendeveloping it to something big, makes code stick easier for me.

BladeLogan asked:

@Sergey Alexandrovich Kryukov How would you rate this code? Do you have anything I can compare it with?
There are several problems:

It's good that you initialized only one instance of System.Random. But, for real randomness (this is pseudo-random number generator), you need to seed a random value in an algorithm. I do it this way:
C#
Random r = new Random(System.DateTime.Now.Ticks.GetHashCode());

See also the Microsoft code sample: DateTime Structure (System)[^].

It's bad that you hard-coded certain things as immediate constants. For example, 26 (and also 10). This is not supportable. What if you change your "abc..." string? You need to calculate this 26 out of the length of this string. Imagine what happens if you decide to change character repertoire. How would you support it. This string, too, does not have to be hard-coded. You can, for example, auto-generate the array from, say, a single character, and required length of character length. More robust approach would be to break this range by first non-letter character. For that purpose, you can use System.Char.IsLetter:
Char.IsLetter Method (System)[^].

So far, this is the worst of your problem, hard-coding, and, moreover, in unsupportable way. Hard-coded 10 is not that bad, but it's in the middle of the code. If you need a constants, it's always better to declarer explicit constant, const int….

Let's go further.

Generation of random string works correctly. But this is a separate functionality. You need to defined it as a separate distinct unit, as type or at least a method. The instance of Random can be passed to this method as a parameter. It's is especially important to separate UI from other parts of code. RandomString is not encapsulated. Generally, you need to hide all you need for random generation in a compact unit which does not give any access to outside context. By the way, instead of "", always use string.Empty. No, it makes no functional difference, but using this readonly field will help you when you get rid of immediate constants, will make your code more supportable — see above.

Some more…

Also, never ever use names like Form1 and button1_Click. It's really good to follow pretty good Windows naming conventions. Never ever use names generated by the designer. The designers "does not know" your intentions. Those names are not designed to be left as is. And of course it's impossibly for the algorithm to generate semantically sensible name. You should take care about that. You should rename everything as you use the names. This is also about the maintainability of your code. If you look at your code few months later, you may not even understand what you did a while ago.

And finally, randomString += … is really bad. You should not use repeated string concatenation; this is inefficient. The reason is: string type is immutable. You don't even concatenate string. You create a new string instance every time. Why? Here is the solution: instead of immutable string type, use its mutable counterpart, the class System.Text.StringBuilder:
StringBuilder Class (System.Text)[^].

That's all I could spot by this time. As you can see, there are many problems, and some of them are serious enough. You need to analyze them all and learn what to pay attention for.

One more thing: your post "Solution 1" is not really a solution. Worse, why would you self-accept this "solution"? Next time, post such matter as a part of your question, using "Improve question".

—SA
 
Share this answer
 
v3
Comments
Maciej Los 30-Dec-15 17:05pm    
5ed!
Sergey Alexandrovich Kryukov 30-Dec-15 17:08pm    
Thank you, Maciej.
—SA
Here's a challenge for you, Logan: write a Class that uses the following Enumeration to return a string with a length the user specifies, composed using the user's type-of-content choices from this Enumeration:
C#
// Enumeration.HasFlag requires .NET >= 4.0
using System;
using System.Collections.Generic;
using System.Text;

namespace LogansRun_2015_1
{
    [Flags]
    public enum RndStrType
    {
       UseAlphaLower = 0x2,
       UseAlphaUpper = 0x4,
       UseWhiteSpace = 0x8,
       UseDigits = 0x10,
       UseOtherCharacters = 0x20
    }

    // you'll write this Class
    public static class RndStringMaker
    {
        private static Random rnd = new Random(DateTime.Now.Millisecond);

        public static string GetRndString(RndStrType rst, int slength)
        {
            StringBuilder result = new StringBuilder(slength);
     
            foreach (RndStrType flag in Enum.GetValues(typeof(RndStrType)))
            {
                if (rst.HasFlag(flag))
                {
                     // for you to write
                }
            }

            for (int i = 0; i < slength; i++)
            {
                // for you to write
            }

            return result.ToString();
        }
    }
}
When your code is complete; I want to see it tested with the following:
C#
string test1 = RndStrMaker.GetRndString(RndStrType.UseAlphaLower, 26);
string test2 = RndStrMaker.GetRndString(RndStrType.UseAlphaUpper, 26);
string test3 = RndStrMaker.GetRndString(RndStrType.UseWhiteSpace, 10);
string test4 = RndStrMaker.GetRndString(RndStrType.UseOtherCharacters, 12);
string test5 = RndStrMaker.GetRndString(RndStrType.UseDigits, 10);
And get results like these:
abcdefghijklmnopqrstuvwxyz  //UseAlphaLower
ABCDEFGHIJKLMNOPQRSTUVWXYZ  //UseAlphaUpper
 \t\n\r // UseWhiteSpace
!#$%(*+,-./:;&lt;=&gt;&gt;?@[\]^_ // UseOtherCharacters
0123456789 // UseDigits
And, if used like this:
C#
string test6 =
RndStrMaker.GetRndString(
    RndStrType.UseAlphaUpper 
    | RndStrType.UseOtherCharacters 
    | RndStrType.UseDigits, 
    35);

// see a result like this:
AKSIO4,T:<8XV9+>1KR<_ZX4@V9R9U>>$=/
And, I would like for you to implement this using only StringBuilders ... without declaring any variable of Type 'String; now, of course, you may have to initialize the StringBuilders you use with a 'string.

While you are developing your code: review the use of Enumerations and the convenient 'HasFlag method added with .NET 4.0. Satisfy yourself that you understand the reason a 'Flags Enumeration uses powers of #2 to allow specifying multiple "choices."

I also want you to study the Enumerable.Range method that came with .NET 3.5, and study how you can use it to automatically generate an IEnumerable of Int32. Hint: you will convert IEnumerables you create into the strings that will initialize the StringBuilders you create.

I want you to study the StringBuilder object, and consider how you can combine them, and access individual characters within them.
 
Share this answer
 
v2
Comments
BladeLogan 30-Dec-15 11:33am    
Looks like this will be a hard one! Mostly because when I look at the code I dont understand anything, well some aprts I understand but I'l try to read up about Enumeration for the next couple of hours & then I'l start working on the problem solving! Thanks for prividing me with this!
BillWoodruff 30-Dec-15 11:43am    
Added some detailed suggestions at the end of the post.
BladeLogan 30-Dec-15 11:49am    
Thank you so much for all the information! This is going to be a blast!
BladeLogan 30-Dec-15 12:00pm    
One crucial question before I start, To use your code I can see that it doesnt contain a static main method suitable for an entry point. Do I just use your concept and make something that has the same outcome or do I use you code just like copy & paste it into a Console Application?
BillWoodruff 30-Dec-15 14:45pm    
I suggest you start like this: assuming you have Visual Studio:

1. create a new Windows Forms Application project named 'LogansRun_2015_1

2. add a new Class named RndStringMaker to the Project, and in that new class copy/paste in the code I show you.

3. put a Button on the Form created for you 'Form1, double-click that Button to create a MousClick EventHandler.

4. in the body of that EventHandler insert the tests I show, but then comment them out ... when you are ready to test, then uncomment the first test, and put a break-point before it, so when you run the app, and you hit the break-point, you can then single-step through the code using F11.

Much easier to debug this way than using a Console App.

Be back on the 2nd. or 3rd. cheers, Bill
C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApplication14
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        char[] letters = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
        Random r = new Random();
        string randomString = "";



        private void button1_Click(object sender, EventArgs e)
        {
            textBox1.Text = randomString;
            for (int i = 0; i < 10; i++)

            {
                randomString += letters[r.Next(0, 26)].ToString() ;


            }
        }

    }
}
 
Share this answer
 
v2
Comments
BladeLogan 29-Dec-15 19:24pm    
@Sergey Alexandrovich Kryukov How would you rate this code? Do you have anything I can compare it with?
Sergey Alexandrovich Kryukov 29-Dec-15 20:18pm    
How could I know about your question? To ask me, you should comment on any my posts and provide a link to your question. It will give me a notification.
See Solution 2.
—SA
Garth J Lancaster 29-Dec-15 20:03pm    
@BladeLogan

... some thoughts

(1)
letters = "abcdefghijklmnopqrstuvwxyz"

ok, what if later you need a set comprising (lower case + upper case + numerals (0-9) + (maybe) special characters)

if how you have it now is enough for you, ie, that satisfies your requirements now and for the future, fine ....

(2)

random ... ok, but we could talk forever on how random is ramdom and such - if you were doing this to be really secure, well, you'd probably want to take a look at RNGCryptoServiceProvider() for example

(3) "randomString += letters[r.Next(0, 26)].ToString() ;" ... 'ick' - please learn how to use StringBuilder

eg

StringBuilder rS = new StringBuilder();
for (int i = 0; i < 10; i++)
{
rS.Append(letters[r.Next(0, 26)].ToString(); // NB : Not sure if you need the ToString() here !
}

randomString = rS.ToString();

(4)

really, your logic for building the random string should be a separate function thats called from within the button1_Click handler - a static function would do - this means it could be used from other buttons/options without repeating code without repeating code :-)
BladeLogan 29-Dec-15 20:11pm    
Thank you for the response, I dont think you know this but im in my 3rd month of C# OOP & your answer was pretty helpful il look into StringBuilder
Sergey Alexandrovich Kryukov 29-Dec-15 20:22pm    
It's only better; it's mean that you could not be too deeply spoiled by bad programming quality typical for many developers; so you have a change to learn how to work better.
Again, Garth cannot get the notification on your comment. You should have commented on his comment, not on your own post.
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900