• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

C#, password checking -- would like to use regular expressions library

ice91785

Senior member
So I have a program....its pretty much done and good to go but I am stuck with password checking.

Basically the password from the user has to be:
1) 6-12 chars
2) One upper
3) One lower
4) One digit

I have read quite a bit about regular expressions library (and how it'd be "easy" to implement in this situation) but am not quite familiar with the syntax of it....

Would anyone be able to help me out?
 
Why are you placing these restrictions on the password? Specifically, the length requirement will make your passwords less secure.

However, you don't need regular expressions in this case to do what you want. It's easier to check the length of the string (ie, if(password.Length <= 12 && password.Length >= 6){ /*hurray, we can keep going*/}), then use some loops (for (int i = 0; i < password.Length; i++){/* Is the char at index i numeric? If so, set a flag to true, and break out of the loop*/) to check and make sure that at least one character matches each of your required characteristics.
 
What are the operator names for checking numbers and checking letters? Something like: IsDigit, IsUpper, IsLower? Also do I need to implement a library to take advantage of these?
 
Originally posted by: presidentender
Why are you placing these restrictions on the password? Specifically, the length requirement will make your passwords less secure.

However, you don't need regular expressions in this case to do what you want. It's easier to check the length of the string (ie, if(password.Length <= 12 && password.Length >= 6){ /*hurray, we can keep going*/}), then use some loops (for (int i = 0; i < password.Length; i++){/* Is the char at index i numeric? If so, set a flag to true, and break out of the loop*/) to check and make sure that at least one character matches each of your required characteristics.

How long would you keep doing this? Who is going to maintain the logic?

Use a regular expression... here is one I used a long time ago:

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{10,15}$

Password between 10-15 characters (you can modify to match your length restrictions), one upper case, one lower case, and one numeric digit. Not tested.

Edit: I hope this is not a homework assignment. I had the regex lying around, so just gave it up.
 
Originally posted by: Dhaval00

Use a regular expression... here is one I used a long time ago:

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{10,15}$

Password between 10-15 characters (you can modify to match your length restrictions), one upper case, one lower case, and one numeric digit. Not tested.

How would the syntax of that run together? Do I do something like

password = ^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{10,15}$

I like the regex idea just have no idea how to implement it.


P.S. This is more of a "learn by doing" personal project for myself, not homework.
 
Originally posted by: Dhaval00
How long would you keep doing this? Who is going to maintain the logic?

I'd assert that it's more likely that the maintainer can't use regular expressions than that he can't read a "for" loop.

Originally posted by: ice91785
What are the operator names for checking numbers and checking letters? Something like: IsDigit, IsUpper, IsLower? Also do I need to implement a library to take advantage of these?

Google. Don't ask other people.
 
I am putting in:

using System.Text.RegularExpressions;
.
.
.
Regex rx = new Regex(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,12}$);

and alternatively also putting in:

Regex rx = new Regex^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,112}$;

and it gives me syntax errors.....

What is my issue here?
 
Originally posted by: presidentender
Originally posted by: Dhaval00
How long would you keep doing this? Who is going to maintain the logic?

I'd assert that it's more likely that the maintainer can't use regular expressions than that he can't read a "for" loop.

I didn't provide a good argument earlier [it was more like lazy reasoning on my part]. In any case, I have heard similar reasoning from a lot of people when it comes to using things like RegEx's, LINQ, anonymous types and delegates, etc., but at the end of the day it comes down to effectively using the tools we've been provided with. Four nested for loops [hypothetically speaking] might be easily readable, but the same job can be done more elegantly and efficiently via a single RegEx. If it is in the API, it should be exploited, IMO.

I could be wrong, but I am pretty sure majority of the people would be willing to use a RegEx in this scenario.
 
Originally posted by: Dhaval00
Originally posted by: presidentender
Originally posted by: Dhaval00
How long would you keep doing this? Who is going to maintain the logic?

I'd assert that it's more likely that the maintainer can't use regular expressions than that he can't read a "for" loop.

I didn't provide a good argument earlier [it was more like lazy reasoning on my part]. In any case, I have heard similar reasoning from a lot of people when it comes to using things like RegEx's, LINQ, anonymous types and delegates, etc., but at the end of the day it comes down to effectively using the tools we've been provided with. Four nested for loops [hypothetically speaking] might be easily readable, but the same job can be done more elegantly and efficiently via a single RegEx. If it is in the API, it should be exploited, IMO.

I could be wrong, but I am pretty sure majority of the people would be willing to use a RegEx in this scenario.

Nested?
for(int k = 0; k < password.NumberOfChars; k++)
{
if(password[k] == password.AllCapitals()[k]) upperOK = true;
if(password[k] == password.AllLittle()[k]) lowerOK = true;
if(Int32.TryConvert(password[k], out int dummy)) numOK = true;
}
if(/*password length stuff from earlier*/) lengthOK = true;
bool passwordValid = (upperOK && lowerOK && numOK && lengthOK);

(This code won't work as written, OP.)

I don't disagree that you can use regexes here. I might even allow that it's one right way to do it. If there are other regexes in the project, I'd say go for it. But you don't need them. I'd just say the straight C# is good enough in this case.

 
Originally posted by: presidentender
Originally posted by: Dhaval00
Originally posted by: presidentender
Originally posted by: Dhaval00
How long would you keep doing this? Who is going to maintain the logic?

I'd assert that it's more likely that the maintainer can't use regular expressions than that he can't read a "for" loop.

I didn't provide a good argument earlier [it was more like lazy reasoning on my part]. In any case, I have heard similar reasoning from a lot of people when it comes to using things like RegEx's, LINQ, anonymous types and delegates, etc., but at the end of the day it comes down to effectively using the tools we've been provided with. Four nested for loops [hypothetically speaking] might be easily readable, but the same job can be done more elegantly and efficiently via a single RegEx. If it is in the API, it should be exploited, IMO.

I could be wrong, but I am pretty sure majority of the people would be willing to use a RegEx in this scenario.

Nested?
for(int k = 0; k < password.NumberOfChars; k++)
{
if(password[k] == password.AllCapitals()[k]) upperOK = true;
if(password[k] == password.AllLittle()[k]) lowerOK = true;
if(Int32.TryConvert(password[k], out int dummy)) numOK = true;
}
if(/*password length stuff from earlier*/) lengthOK = true;
bool passwordValid = (upperOK && lowerOK && numOK && lengthOK);

(This code won't work as written, OP.)

I don't disagree that you can use regexes here. I might even allow that it's one right way to do it. If there are other regexes in the project, I'd say go for it. But you don't need them. I'd just say the straight C# is good enough in this case.

Which is fine until the password requirements change and somebody else has to maintain that code. Regex's are very easy to maintain, that code isn't so easy to maintain.

 
Originally posted by: Crusty
Which is fine until the password requirements change and somebody else has to maintain that code. Regex's are very easy to maintain, that code isn't so easy to maintain.

Not always. And... if that code's not easy to maintain, I'm really, really sorry.
 
Originally posted by: presidentender
Originally posted by: Crusty
Which is fine until the password requirements change and somebody else has to maintain that code. Regex's are very easy to maintain, that code isn't so easy to maintain.

Not always. And... if that code's not easy to maintain, I'm really, really sorry.

Nice link. I've bookmarked it.
 
Originally posted by: ice91785
I am putting in:

using System.Text.RegularExpressions;
.
.
.
Regex rx = new Regex(^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,12}$);

and alternatively also putting in:

Regex rx = new Regex^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,112}$;

and it gives me syntax errors.....

What is my issue here?

Are you learning C# as well? I only ask because, assuming you're using Visual Studio, when you typed out "Regex rx = new Regex(" you should have seen Intellisense pop up and let you know the constructor for Regex takes a parameter of a String (or two parameters: String,RegexOptions). You need to pass in the regular expression as a string.
 
Yes I am new to C# (could I make it more obvious? lol) ....

Anyway I gave up on regex and ended up using a handful of "if" statements, all inside a loop....seems to have worked out. Probably not the most efficient way but again i'm just learnin'
 
Let me throw you a bone about a very different way of matching characters. Assuming you're using ASCII (not Unicode) characters - and I think C# defaults to Unicode so you should throw in a if(char > 128) to avoid that problem - you can make an array of numbers relating to each and every character.

In this case, I would make, say, an array named charbits, with the digits 0-9 equal to 1, a-z equal to 2, and A-Z equal to 4 (yes, 4), with the other entries 0. Now, for each character in the password, you can do:

b |= charbits[password[ i ]];

And if, in the end, b=7, you know all the criteria were met.
 
Originally posted by: ice91785
Yes I am new to C# (could I make it more obvious? lol) ....

Anyway I gave up on regex and ended up using a handful of "if" statements, all inside a loop....seems to have worked out. Probably not the most efficient way but again i'm just learnin'

If you're doing this just to learn then try it out both ways, once you understand regular expressions and can identify places they can be used you'll have another tool at your disposal.

You were really close before, you just need to wrap your regexp in quotes to pass it as a string. (I haven't tested this but it looks right)

Regex rx = new Regex(@"^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,12}$");

If you looked at the MSDN link provided earlier and scroll down to the examples section you can see it in use. The MSDN is a great resource so be sure to use it!


The @ before the string might throw you off. This symbol tells it not to process the escape sequences. For example if you had a string that had "\t" it would process that as a tab, but we wouldn't want that in a Regex, since the regular expression is doing the processing. If you didn't have the @ you'd have to use \\ to escape out the single backslashes

More from the MSDN. This time on strings:
"The advantage of @-quoting is that escape sequences are not processed, which makes it easy to write, for example, a fully qualified file name:
@"c:\Docs\Source\a.txt" // rather than "c:\\Docs\\Source\\a.txt"
 
Originally posted by: presidentender
Originally posted by: Crusty
Which is fine until the password requirements change and somebody else has to maintain that code. Regex's are very easy to maintain, that code isn't so easy to maintain.

Not always. And... if that code's not easy to maintain, I'm really, really sorry.

For me, this was too big a thing to leave hanging in there... you know, programmers and their big egos. Finally gathered some time to run a test (I've come up with many similar ones in the past to prove the point).

Refer to the code: http://rafb.net/p/shpG7m65.html

Couple of issues before I start discussing my points in detail:
1) I stole the random string generation code from a blogpost, so credit to the original poster. As a side note, there is a bug, but that doesn't matter.
2) The manualMatches collection ends up with more matches (just a few more) - I think this is because the logic is missing something.


On average, the regex method is two to three times faster. I don't think the gap will widen because I have run similar tests in the past, and this scenario is not an exception. Having said that, maybe you can enhance your logic and see if you can reduce the time-to-completion on the manual method. My guess is that the call to TryParse is the most time consuming... I believe it is wrapped within a try a catch which puts extra burden on the CLR.

Why do I emphasize this (using regex)? Primarily, because this scenario lends itself to using regexes. Secondly, I'll try and squeeze out the extra ounce of performance if I have to (needless to say, not at the expense of making the code crappy and convoluted) using the tools I know [sane-fully]. In this case, we're talking about the Framework, not necessarily using something like C++ or Assembly to squeeze the extra ounce of performance.

I don't see what Jeff Atwood's article has to do anything with the discussion that we have been having here. This is a perfect scenario where a regular expression should be used. If you've been coding/programming for a few months, you better know basic Regex syntax... there is no excuse for it. Atwood is arguing about the overuse of regexes. I'd say this is a case where the regex is pretty simple. In fact, so simple, that I was able to pull it out of my head (and that that I have used it many times).

This is not meant to be an ad hominem argument, so again, please ignore any of the statements that sound too 'personal.' I'll back off from promoting the use of a regex if you can still come up with a faster way to check the password using the "if" logic. For me, performance is important, which is the point I should have made instead of asking "who is going to maintain that?" For the OP, performance may be secondary, but even in that case, that isn't reason enough to not use a RegEx.

Edit 1: As a side note, I know I sound hasty, but time is of essence 🙂. Ignore any and all grammatical errors. Also, I remembered the code has a LINQ statement at the end... I was trying to pinpoint the bug that was causing the # of matches in manualMatches to be larger.. ran out of time.

Edit 2: Just observed that the manual method is not even checking the entire string (line 108). Which means, if we modify the logic, chances are that the manual method will be even slower.
 
Originally posted by: Dhaval00
For me, this was too big a thing to leave hanging in there... you know, programmers and their big egos. Finally gathered some time to run a test (I've come up with many similar ones in the past to prove the point).

Refer to the code: http://rafb.net/p/shpG7m65.html

Kudos for running a real experiment. Its good to know that Regexes are fast in C# (it makes sense, after all).

EDIT: Apologies for messing up where the quote ends...
 
Originally posted by: Dhaval00
Originally posted by: presidentender
Originally posted by: Crusty
Which is fine until the password requirements change and somebody else has to maintain that code. Regex's are very easy to maintain, that code isn't so easy to maintain.

Not always. And... if that code's not easy to maintain, I'm really, really sorry.

For me, this was too big a thing to leave hanging in there... you know, programmers and their big egos. Finally gathered some time to run a test (I've come up with many similar ones in the past to prove the point).

Refer to the code: http://rafb.net/p/shpG7m65.html

Couple of issues before I start discussing my points in detail:
1) I stole the random string generation code from a blogpost, so credit to the original poster. As a side note, there is a bug, but that doesn't matter.
2) The manualMatches collection ends up with more matches (just a few more) - I think this is because the logic is missing something.


On average, the regex method is two to three times faster. I don't think the gap will widen because I have run similar tests in the past, and this scenario is not an exception. Having said that, maybe you can enhance your logic and see if you can reduce the time-to-completion on the manual method. My guess is that the call to TryParse is the most time consuming... I believe it is wrapped within a try a catch which puts extra burden on the CLR.

Why do I emphasize this (using regex)? Primarily, because this scenario lends itself to using regexes. Secondly, I'll try and squeeze out the extra ounce of performance if I have to (needless to say, not at the expense of making the code crappy and convoluted) using the tools I know [sane-fully]. In this case, we're talking about the Framework, not necessarily using something like C++ or Assembly to squeeze the extra ounce of performance.

I don't see what Jeff Atwood's article has to do anything with the discussion that we have been having here. This is a perfect scenario where a regular expression should be used. If you've been coding/programming for a few months, you better know basic Regex syntax... there is no excuse for it. Atwood is arguing about the overuse of regexes. I'd say this is a case where the regex is pretty simple. In fact, so simple, that I was able to pull it out of my head (and that that I have used it many times).

This is not meant to be an ad hominem argument, so again, please ignore any of the statements that sound too 'personal.' I'll back off from promoting the use of a regex if you can still come up with a faster way to check the password using the "if" logic. For me, performance is important, which is the point I should have made instead of asking "who is going to maintain that?" For the OP, performance may be secondary, but even in that case, that isn't reason enough to not use a RegEx.

Edit 1: As a side note, I know I sound hasty, but time is of essence 🙂. Ignore any and all grammatical errors. Also, I remembered the code has a LINQ statement at the end... I was trying to pinpoint the bug that was causing the # of matches in manualMatches to be larger.. ran out of time.

Edit 2: Just observed that the manual method is not even checking the entire string (line 108). Which means, if we modify the logic, chances are that the manual method will be even slower.

Without getting into a debate over the better method... (I don't think performance is a valid argument here in either case)

This manual method code is creating multiple string copies each time through the inner loop, try this instead:

for (int k = 0; k < s.Length; k++)
{
digitOK = digitOK || Char.IsDigit(s[k]);
upperOK = upperOK || Char.IsUpper(s[k]);
lowerOK = lowerOK || Char.IsLower(s[k]);
}

Results are now an order of magnitude improved:

Total time elapsed (manual method): 118.5561; Total matches: 256863
Total time elapsed (regex method): 1760.1189; Total matches: 256863


 
Originally posted by: Dhaval00
Originally posted by: presidentender
Originally posted by: Crusty
Which is fine until the password requirements change and somebody else has to maintain that code. Regex's are very easy to maintain, that code isn't so easy to maintain.

Not always. And... if that code's not easy to maintain, I'm really, really sorry.

For me, this was too big a thing to leave hanging in there... you know, programmers and their big egos. Finally gathered some time to run a test (I've come up with many similar ones in the past to prove the point).

Refer to the code: http://rafb.net/p/shpG7m65.html

Couple of issues before I start discussing my points in detail:
1) I stole the random string generation code from a blogpost, so credit to the original poster. As a side note, there is a bug, but that doesn't matter.
2) The manualMatches collection ends up with more matches (just a few more) - I think this is because the logic is missing something.


On average, the regex method is two to three times faster. I don't think the gap will widen because I have run similar tests in the past, and this scenario is not an exception. Having said that, maybe you can enhance your logic and see if you can reduce the time-to-completion on the manual method. My guess is that the call to TryParse is the most time consuming... I believe it is wrapped within a try a catch which puts extra burden on the CLR.

Why do I emphasize this (using regex)? Primarily, because this scenario lends itself to using regexes. Secondly, I'll try and squeeze out the extra ounce of performance if I have to (needless to say, not at the expense of making the code crappy and convoluted) using the tools I know [sane-fully]. In this case, we're talking about the Framework, not necessarily using something like C++ or Assembly to squeeze the extra ounce of performance.

I don't see what Jeff Atwood's article has to do anything with the discussion that we have been having here. This is a perfect scenario where a regular expression should be used. If you've been coding/programming for a few months, you better know basic Regex syntax... there is no excuse for it. Atwood is arguing about the overuse of regexes. I'd say this is a case where the regex is pretty simple. In fact, so simple, that I was able to pull it out of my head (and that that I have used it many times).

This is not meant to be an ad hominem argument, so again, please ignore any of the statements that sound too 'personal.' I'll back off from promoting the use of a regex if you can still come up with a faster way to check the password using the "if" logic. For me, performance is important, which is the point I should have made instead of asking "who is going to maintain that?" For the OP, performance may be secondary, but even in that case, that isn't reason enough to not use a RegEx.

Edit 1: As a side note, I know I sound hasty, but time is of essence 🙂. Ignore any and all grammatical errors. Also, I remembered the code has a LINQ statement at the end... I was trying to pinpoint the bug that was causing the # of matches in manualMatches to be larger.. ran out of time.

Edit 2: Just observed that the manual method is not even checking the entire string (line 108). Which means, if we modify the logic, chances are that the manual method will be even slower.

/agree 100% I was just too lazy to attempt to refute 😛

The manual loop was a bad way, but to be fair it was mentioned it wouldn't work as is and I'm sure not much thought was put into it. Some additions of stuff like short circuiting in the ifs to prevent checking a test that's already passed will speed it up dramatically.

I agree with Templeton in that performance isn't really that big of a deal. I forget who mentioned it in the other thread about regex's and the basic idea was that if you're using regex's to scan user input then you're going to spend 99% of you time waiting for user input so the performance really doesn't matter as much as one would think.

 
Originally posted by: Templeton

This manual method code is creating multiple string copies each time through the inner loop, try this instead:

for (int k = 0; k < s.Length; k++)
{
digitOK = digitOK || Char.IsDigit(s[k]);
upperOK = upperOK || Char.IsUpper(s[k]);
lowerOK = lowerOK || Char.IsLower(s[k]);
}

Results are now an order of magnitude improved:

Total time elapsed (manual method): 118.5561; Total matches: 256863
Total time elapsed (regex method): 1760.1189; Total matches: 256863

:thumbsup:

You're right, the performance of what I wrote is atrocious. I agree with Dhaval00 and others that performance isn't an issue here, so the improved performance of the manual method in this case is moot (we do this once per password... the time it takes a human being to type a password and click the button is much greater than the time it takes to check the password, even in my original don't-even-try-it method). Given that the OP is just looking to improve his skills, a regex is probably the best bet (ESPECIALLY if he doesn't know regexes).

In a real-world setting, I'd let the developer who was to write the code make the call. If it was me, I'd do what Templeton did... but if you'd already done it with a regex and I inherited your code, I wouldn't refactor it into a loop.
 
Originally posted by: Templeton

for (int k = 0; k < s.Length; k++)
{
digitOK = digitOK || Char.IsDigit(s[k]);
upperOK = upperOK || Char.IsUpper(s[k]);
lowerOK = lowerOK || Char.IsLower(s[k]);
}

Results are now an order of magnitude improved:

Total time elapsed (manual method): 118.5561; Total matches: 256863
Total time elapsed (regex method): 1760.1189; Total matches: 256863

Great improvement! I'd be more than happy to back off (w.r.to this scenario... more like w.r.to the OP's specific, lone requirement).

I am still going to nitpick, at a higher level, on the basis that the "if" logic has the potential to "outgrow" if you get into more complex requirements - things like at least two digits, three uppers, etc. Maybe it's just a rant, but I'm on the receiving end of some old VB6 applications that used similar methods to manage passwords. Having said that, I have been working on too many things to pursue this topic seriously - I'd [now] be interested to see what the code looks like if you have things like two uppers, three digits, etc. (if someone here has time). Also, as a side note, I haven't pondered about ways to enhance the regex, just as I did not look at ways to enhance the original logic presidentender posted.

In any case, good improvement, Templeton.
 
Back
Top