2

I am trying to use regular expressions with my C# code, and I can find a few examples here on what those regular expressions might look like for my cause, but nowhere can I tell how I am supposed to (syntactically) implement that into my logic and code.

I have tried setting up an external .cs file and then calling the method, but the value returned is unable to be casted or worked with in any way. The code can be found here:Checking strings for a strong enough password

In any event, I just want to know how I can check (and test against) values in a password to make sure it is up to standards that I specify.

A better way than suggesting to use regular expressions (since information on how to incorporate them into my own specific logistical setup is both very sparse and very confusing)

...is suggesting how it can be done without them.

I know I could use

foreach(char c in myString)

and then test individually, character by character, but I was hoping there was a better way that can either be regex, explained (that is, explained how to call this suggestion into action, not just posting a string of seemingly (but not) random characters and told, hey use that!), or not using regex at all, but somekind of shorthand, perhaps.

Truth is I would use regular expressions, but every time I look them up I can't seem to find anything that is useable by me in WebMatrix.

I want to be able to test a password to be sure that it has both an uppercase and a lowercase number. In addition I need to check for at least one number.

UPDATE: Okay, allow me to rephrase my question, maybe I am being confusing...

How does regex work in webmatrix razor (C#). Please show how the regex actually works (I can't seem to find a clear, or even close to clear, answer on this on the web for webmatrix), then please show how it can be put (directly or indirectly) into if logic, on my cshtml page, so that I can actually check against it.

Community
  • 1
  • 1
VoidKing
  • 6,282
  • 9
  • 49
  • 81

3 Answers3

3

A Regular Expression (Regex), as you will find out, is a tool used in matching text against a pattern and even extracting or replacing matches in the source text.

To do this the Regex engine (which exists in the .Net framework inside the namespace System.Text.RegularExpressions) uses some established patterns that represent certain kinds of chars.

To use a Regex, you pass it the pattern agains which a text will be tested and the text itself.

For instance, the following snippet tests if there are lowercase letters in the text:

using System.Text.RegularExpressions;
... 
var Pattern = "[a-z]";
if (Regex.IsMatch(SomeText, Pattern)) {
//... there is at least one lower case char in the text
}

The pattern used above estates that we are interested in a range of chars from lowercase "a" to lowercase "z".

A pattern to require at least one lowercase letter, one digit and one uppercase letter could probably be something like

@"[\d]+[a-z]+[A-Z]|[\d]+[A-Z]+[a-z]|[a-z]+[\d]+[A-Z]|[a-z]+[A-Z]+[\d]|[A-Z]+[\d]+[a-z]|[A-Z]+[a-z]+[\d]"

As you can see, a Regex pattern can be as simple as in the first example, but may escalate fast in complexity depending on the kind of information you want to check or extract.

In the Regex above, the items between square brackets are called character classes. The plus sign after an element is a quantifier, it indicates that the item may appear one or more times. Items separated by a vertical bar indicate alternatives. The "\d" pattern represents any digit from "0" to "9".

You don't really need a Regex to check the password strength in your application, but using then instead of the explicit tests you are currently making would (in my opinion), greatly improve your program's readability:

using System.Text.RegularExpressions;
... 
if (!Regex.IsMatch(password, "[A-Z]")) {
  errorMessage = "Your password must contain at least one uppercase character."; 
} else if (!Regex.IsMatch(password, "[a-z]") {
  errorMessage = "Your password must contain at least one lowercase character."; 
} else if (! Regex.IsMatch(password, @"[\d]")){
  errorMessage = "Your password must contain at least one numerical character."; 
}
...
Baba
  • 94,024
  • 28
  • 166
  • 217
Branco Medeiros
  • 729
  • 4
  • 10
  • Very nice explanation. Best I've seen so far! I'm accepting your answer as the best one (cuz it is) – VoidKing Oct 16 '12 at 13:19
  • Why do you have to repeat them so many times (in different order) in your example above that checked all at once? Also why are no quantifiers needed in the above example that tests them separately? Sorry, still not entirely sure how the system checks the password against the pattern, character for character. – VoidKing Oct 16 '12 at 13:24
2

If you're trying to do this test on the page before the information is sent to the server, you can check with javascript and regex. I think this way is best, since you eliminate additional trips to the server. It can pass the javascript validation, post the data to your site, and you can validate more on the server (in case the user has javascript off). Razor syntax helps in the page rendering, but won't help you when the user is doing stuff on the page.

Pattern: ((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,15})

This is requiring at least 1 digit, 1 lowercase and 1 uppercase. It's also requiring the password to be between 8 and 15 characters long (inclusive). You can easily change the length requirements in the pattern. For example, if you wanted it to be at least 8 characters, but no max:

((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,})

To use this in javascript (I did use jQuery to wire up my click event in my test and get the password from the input):

var password = $('#password').val();
var pattern = /((?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,15})/;
var pass = pattern.test(password);

A Fiddle showing it in action: http://jsfiddle.net/gromer/chF4D/1/

Gromer
  • 9,861
  • 4
  • 34
  • 55
  • I am not trying to do this before they post, but after. If I could check it in JavaScript, I would still have to check it on the server, in case there javascript is off, etc. So why not just do it after post on the server side in the first place rather than both? – VoidKing Oct 15 '12 at 19:48
  • I'd do it in both places. So since you're wanting to check on the server, Razor has nothing to do with this. Here's some info on using the `Regex` class in C#: http://www.dotnetperls.com/regex-match – Gromer Oct 15 '12 at 19:49
  • Razor is what's being used to _render_ the page. It isn't the place to check the validity of data posted to the server. – Gromer Oct 15 '12 at 19:51
  • Right, but just because it isn't used to check validity, doesn't mean that it's not server-side. Besides if you right your code within the cshtml file (like at the top using @{ code here }) I think it's still razor, and since you can use if(IsPost) than, yup, can still be used to check validity too! And yet, also still razor! – VoidKing Oct 15 '12 at 19:52
  • Well, that isn't using Razor, that's C# code inside a code block in your Razor file. Regardless, the proper validation points are in the javascript, and then in your post action method in your controller. I don't see why you would want this code in the Razor file at all. – Gromer Oct 15 '12 at 19:55
  • Umm, well, I am kind of on my own on this and using whatever works at this point (so long as it doesn't compromise security). It's not like I'm a 30 veteran at C# or anything, but I think the best way (for me) to do this is to just use foreach(char c in password) and use a bunch of sloppy lengthy code. At least it will work, which is more than I am getting with regex. – VoidKing Oct 15 '12 at 20:01
  • Thanks for trying to help, anyway – VoidKing Oct 15 '12 at 20:02
  • I don't see why I wouldn't want it in my razor file either... if there is actually such a thing as a razor file and not just a cshtml or vbhtml file. – VoidKing Oct 15 '12 at 20:07
0

Well I know this isn't the way to properly do this, (the proper way is using regular expressions, which is what I was attempting to figure out) but if you are like me, and sick of asking/searching the same question over and over again, without getting any entirely useful feedback, this is what worked for me.

    int Ucount = 0;
    int Lcount = 0;
    int Ncount = 0;
    foreach(char c in password)
    {
        if(c!='A' && c!='B' && c!='C' && c!='D' && c!='E' && c!='F' && c!='G' && c!='H' && c!='I' && c!='J' && c!='K' && c!='L' && c!='M' && c!='N' && c!='O' && c!='P' && c!='Q' && c!='R' && c!='S' && c!='T' && c!='U' && c!='V' && c!='W' && c!='X' && c!='Y' && c!='Z')
        {
            Ucount++;
            if(Ucount >= password.Length)
            {
                errorMessage = "Your password must contain at least one uppercase character.";
            }
        }

        if(c!='a' && c!='b' && c!='c' && c!='d' && c!='e' && c!='f' && c!='g' && c!='h' && c!='i' && c!='j' && c!='k' && c!='l' && c!='m' && c!='n' && c!='o' && c!='p' && c!='q' && c!='r' && c!='s' && c!='t' && c!='u' && c!='v' && c!='w' && c!='x' && c!='y' && c!='z')
        {
            Lcount++;
            if(Lcount >= password.Length)
            {
                errorMessage = "Your password must contain at least one lowercase character.";
            }
        }

        if(c!='0' && c!='1' && c!='2' && c!='3' && c!='4' && c!='5' && c!='6' && c!='7' && c!='8' && c!='9')
        {
            Ncount++;
            if(Ncount >= password.Length)
            {
                errorMessage = "Your password must contain at least one numerical character.";
            }
        }
    }

Again, please note that the proper way to do this is to use regular expressions, but this code works fine for me, and I got to end the wild goose chase that was understanding regular expressions.

UPDATE: Or, if you want to do it right, read Branco Medeiros's post above, he posted after I posted this, and his way is the right way to do it (provided you don't want to do it with JavaScript before it is sent to the server. If your app is like mine and not resource intensive enough to need JavaScript to do this, use Branco Medeiros's example above).

VoidKing
  • 6,282
  • 9
  • 49
  • 81
  • 1
    Rather than editing the answer to read "removed...", you should delete it yourself. – Sam Oct 15 '12 at 20:35