• (cs) in reply to Zylon
    Zylon:
    WTF is "Sting Verification"?
    Many miles away Something crawls from the slime At the bottom of a dark Scottish lake
  • AGray (unregistered) in reply to C-Derb
    C-Derb:
    Mmmm...I love me some recursion:
    private bool ContainsChars(string destination)
    {
      if (string.IsNullOrEmpty(destination)) return false;
      int i;
      return int.TryParse(destination.Substring(0, 1), out i) ? ContainsChars(destination.Substring(1)) : true;
    }
    

    I love me some recursion too, but recursion is slow; is that really the best way to validate the string?

    class Example
    {
        private List<string> forbidden = new List<string> {0,1,2,3,4,5,6,7,8,9};
    
        public string ContainsChars(string destination)
        {
            for(int i = 0; i < destination.Length; i++)
            {
               if(forbidden.Contains(destination[i])
               {
                   return "0";
               }
            }
    
            return "1";
        }
    }

    I think that would be a bit cleaner.

    CAPTCHA: Persto - Presto when said frist!

  • PRMan (unregistered) in reply to @Deprecated
    @Deprecated:
    Wow, so many inefficiencies I don't even know where to start!
    • Rebuilds array every time it is called
    • Uses an array instead of c >= '0' and c <= '9'
    • Calls substring repeatedly in inner loops
    • Does not exit early from outer for loop
    • Using strings instead of booleans

    Ugh. Maybe the array is used in case sometime in the future, a new number is added between '4' and '5'.

    Such as Derf...

  • Ryan (unregistered)

    Looks like a good place to use Regular Expressions (try http://www.ultrapico.com/Expresso.htm).

    Additionally it validates an empty destination of string.empty since validChars defaults to true, which probably isn't the intended behavior and would help your case for cleaning it up.

  • C-Derb (unregistered) in reply to AGray
    AGray:
    I love me some recursion too, but recursion is slow; is that really the best way to validate the string?
    No, recursion is not the best way for this particular validation requirement. I was merely throwing it out there as yet another approach. But, to be fair, it is better than the original "solution".
  • SG_01 (unregistered)

    return destination.All(x => char.IsNumber(x));

    Was that so hard? (Note that this allows numbers that cannot be parsed on the system due to them being too large)

  • AGray (unregistered) in reply to C-Derb
    C-Derb:
    AGray:
    I love me some recursion too, but recursion is slow; is that really the best way to validate the string?
    No, recursion is not the best way for this particular validation requirement. I was merely throwing it out there as yet another approach. But, to be fair, it is better than the original "solution".

    Fair point.

    CAPTCHA: consequat - a Sasquatch-sized consequence of writing bad code!

  • Dathan (unregistered) in reply to AGray

    AGray, you realize your method is completely wrong, right?

  • SG_01 (unregistered) in reply to Ryan
    Ryan:
    Looks like a good place to use Regular Expressions (try http://www.ultrapico.com/Expresso.htm).

    Hrmm, this looks amazing, no idea that existed grabs

  • JJ (unregistered) in reply to Matt
    Matt:
    return Regex.Match("[\d]", destination).Success;
    Let me count the fail.
    1. Your input and pattern parameters are in the wrong order. The pattern comes second.

    2. Compiler error: Unrecognized escape sequence. Put @ in front of the pattern or double the backslash.

    3. Your pattern will match any string with a number in it anywhere.

  • Oops (unregistered) in reply to SG_01
    SG_01:
    return destination.All(x => char.IsNumber(x));

    Was that so hard? (Note that this allows numbers that cannot be parsed on the system due to them being too large)

    Hard? No. Correct? Also No.

    These calls will both return true with your version: checkChars("ⅮⅠⅯⅱ"); checkChars("⅞፼൱");

    IsDigit is what you wanted here.

  • Oops (unregistered) in reply to Oops
    Oops:
    SG_01:
    return destination.All(x => char.IsNumber(x));

    Was that so hard? (Note that this allows numbers that cannot be parsed on the system due to them being too large)

    Hard? No. Correct? Also No.

    These calls will both return true with your version: checkChars("ⅮⅠⅯⅱ"); checkChars("⅞፼൱");

    IsDigit is what you wanted here.

    Oops..I got it wrong too. There are 460 digit chars in unicode.

    Guess we gotta go with: destination.All(x => x >= '0' && x <= '9');

  • ozzie (unregistered) in reply to Oops

    Oh I see the problem, he didn't use xml.

  • User.FullName (unregistered)

    I tried texting 1-800-suicide and my phone told me my very character is invalid. _esteem--;

  • SG_01 (unregistered) in reply to Oops
    Oops:
    Oops:
    SG_01:
    return destination.All(x => char.IsNumber(x));

    Was that so hard? (Note that this allows numbers that cannot be parsed on the system due to them being too large)

    Hard? No. Correct? Also No.

    These calls will both return true with your version: checkChars("ⅮⅠⅯⅱ"); checkChars("⅞፼൱");

    IsDigit is what you wanted here.

    Oops..I got it wrong too. There are 460 digit chars in unicode.

    Guess we gotta go with: destination.All(x => x >= '0' && x <= '9');

    The only requirement stated was that the thing only contained numbers, which is exactly what it does. I never said it matched what the code does :D

  • bob (unregistered)

    Getting paid by the line surely...

  • SG_01 (unregistered) in reply to User.FullName

    Well, if you were parsing phone numbers, you'd have to at least have something along the lines of:

    ^( *+ *[0-9]+)?( *( *[0-9]+ *))( *[0-9]+| *- [0-9]+) *$

    Of course in this, the characters (, ), - and space get removed, + gets replaced by whatever the international dialling code is, however before that you might want to remove the entire international block all together if it's for the current country. However if this is the case, you will need to insert an extra 0 for some countries. Also, if you want to do this, you'll need to figure out the exact length of the country code, making it become something like:

    *+ *(1|[2-4][0-9]|...)

    Then you get the locational area, this is usually the first block after the internal code, and may be omitted to dial local... This is usually the part between the parentheses, however as users tend to get this part wrong. In the end, this requires a whole separate parsing round, so you may as well have been writing your own parser for this.

    If you want to support letters, you can do that in the last couple of blocks as well, but then you'll need to convert them to numbers as well.

    TL;DR: Phone numbers: A whole lot harder than your simple 0-9 digit parsing.

  • barf 4eva (unregistered)

    Damn.... that's pretty fkn bad..

  • KaeruCT (unregistered)

    Yeah, because you couldn't just have used regex

  • Everyone's a critic (unregistered) in reply to @Deprecated

    Does it work? Yes.

  • Dick Head (unregistered) in reply to Zylon
    Zylon:
    WTF is "Sting Verification"?
    A determination of whether any song has repetitive, nonsensical lyrics towards the end. I guess a regex could be used here somehow.
  • Mathlete (unregistered)

    TRWTF is that almost every "fixed" version in this comments thread is wrong! You could get at least a week's worth of articles from it.

    This will maintain the current logging and return type while removing the stupid:

    private string checkChars(string destination)
    {
        var invalidChars = destination.Where(x => x < '0' || x > '9').ToList();
        
        if (invalidChars.Any())
        {
            foreach (var invalidChar in invalidChars)
                LogDebug("checkChars -> Invalid character found: " + invalidChar);
            LogDebug("checkChars -> Invalid characters found");
    
            return "1";
        }
        
        LogDebug("checkChars -> All characters ok");
    
        return "0";
    }
    

    Of course if you just want a boolean, you could use any of the following:

    
    public bool CheckChars(string destination) { return destination.All(x => '0' <= x && x <= '9'); }
    
    public bool CheckChars(string destination) { return Regex.IsMatch(destination, @"^\d*$"); }
    
    public bool CheckChars(string destination)
    {
        foreach (var c in destination)
        {
            if (c < '0' || c > '9')
                return false;
        }
    
        return true;
    }
    
  • lietu (unregistered)

    In many "modern" languages this could be simplified basically to something like: return (string)(int)destination === destination

    E.g. in JavaScript: return String(parseInt(destination, 10)) === destination

  • Mr Obvious (unregistered) in reply to LabSpecimen
    LabSpecimen:
    We had fun with this one at work. Here's my version:

    private boolean checkChars(string destination) { int cnt = 0; if (destination != null) { for (int i = 0; i < destination.length(); i++) { (destination.charAt(i) == '0') ? cnt++ : (destination.charAt(i) == '1') ? cnt++ : (destination.charAt(i) == '2') ? cnt++ : (destination.charAt(i) == '3') ? cnt++ : (destination.charAt(i) == '4') ? cnt++ : (destination.charAt(i) == '5') ? cnt++ : (destination.charAt(i) == '6') ? cnt++ : (destination.charAt(i) == '7') ? cnt++ : (destination.charAt(i) == '8') ? cnt++ : (destination.charAt(i) == '9') ? cnt++ : cnt = cnt; } } return (destination != null && cnt == destination.length()) ? true : false; }

    Ummm... it looks like one of your variables is missing the letter 'u'.
  • lietu (unregistered) in reply to Mathlete
    Mathlete:
    Of course if you just want a boolean, you could use any of the following:

    .. if instead of boolean you want "1" or "0", why not just add ?"1":"0" or whichever way they wanted the return value ..

  • (cs) in reply to @Deprecated
    @Deprecated:
    Wow, so many inefficiencies I don't even know where to start!
    • Rebuilds array every time it is called
    • Uses an array instead of c >= '0' and c <= '9'
    • Calls substring repeatedly in inner loops
    • Does not exit early from outer for loop
    • Using strings instead of booleans

    Ugh. Maybe the array is used in case sometime in the future, a new number is added between '4' and '5'.

    Oh, du-uh! I'll pick one for you, then you work out whether you can do likewise. Ready? Set? Go!

    4.5

  • (cs) in reply to Mr Obvious
    Mr Obvious:
    LabSpecimen:
    We had fun with this one at work. Here's my version:

    private boolean checkChars(string destination) { int cnt = 0; if (destination != null) { for (int i = 0; i < destination.length(); i++) { (destination.charAt(i) == '0') ? cnt++ : (destination.charAt(i) == '1') ? cnt++ : (destination.charAt(i) == '2') ? cnt++ : (destination.charAt(i) == '3') ? cnt++ : (destination.charAt(i) == '4') ? cnt++ : (destination.charAt(i) == '5') ? cnt++ : (destination.charAt(i) == '6') ? cnt++ : (destination.charAt(i) == '7') ? cnt++ : (destination.charAt(i) == '8') ? cnt++ : (destination.charAt(i) == '9') ? cnt++ : cnt = cnt; } } return (destination != null && cnt == destination.length()) ? true : false; }

    Ummm... it looks like one of your variables is missing the letter 'u'.

    Reminds me of someone's FORTRAN program when I was considerably younger: dSylelixc colleague wanted to use NCOUNT as a variable but instead transposed the 2nd and 3rd letters. Oh how we laughed.

  • Mathlete (unregistered) in reply to lietu
    lietu:
    Mathlete:
    Of course if you just want a boolean, you could use any of the following:

    .. if instead of boolean you want "1" or "0", why not just add ?"1":"0" or whichever way they wanted the return value ..

    Because the equivalent version I posted has multiple return statements? If it had a valid flag and a single return then obviously I would have used

    return valid ? "0" : "1";

    Also out of curiosity I also ran the following benchmark code:

        public static void Main(string[] args)
        {
            const string valid = "193485923905820394029850298402983409284032840238402984";
            const string invalid = "34534534503985039845038450394850394850398503498503985a";
    
            foreach (var func in new Func<string, bool>[] { ValidateLinq, ValidateRegex, ValidatePrecompiledRegex, ValidateForLoop })
            {
                var startTime = DateTime.Now;
    
                for (var i = 0; i < 1000000; i++)
                {
                    func(valid);
                    func(invalid);
                }
    
                var endTime = DateTime.Now;
    
                Console.Out.WriteLine(func.Method.Name + ": " + endTime.Subtract(startTime).TotalMilliseconds);
            }
    
            Console.In.ReadLine();
        }
    
        private static bool ValidateLinq(string str) { return str.All(x => '0' <= x && x <= '9'); }
    
        private static bool ValidateRegex(string str) { return Regex.IsMatch(str, @"^\d*$"); }
    
        private static readonly Regex ValidatorRegex = new Regex(@"^\d*$");
        private static bool ValidatePrecompiledRegex(string str) { return ValidatorRegex.IsMatch(str); }
    
        private static bool ValidateForLoop(string str)
        {
            foreach (var c in str) if (c < '0' || c > '9') return false; 
            return true;
        }
    

    The results were interesting:

    ValidateLinq: 1239 ValidateRegex: 6241 ValidatePrecompiledRegex: 5449 ValidateForLoop: 171

  • Peter Olsen (unregistered) in reply to @Deprecated

    Actually, a new integer between 3 and 4 have recently been found in Denmark.

    http://translate.google.com/translate?sl=auto&tl=en&js=n&prev=_t&hl=en&ie=UTF-8&layout=2&eotf=1&u=http%3A%2F%2Frokokoposten.dk%2F2011%2F10%2F14%2Fbreaking-heltal-mellem-3-og-4-fundet-naer-silkeborg%2F&act=url

  • Benny Bottema (unregistered)

    not to mention the == equality checks with Strings.

  • Jan (unregistered) in reply to @Deprecated
    @Deprecated:
    Ugh. Maybe the array is used in case sometime in the future, a new number is added between '4' and '5'.

    You laugh now, but just wait I tell you, you'll see, you'll all see!

  • erikr (unregistered) in reply to @Deprecated

    I guess a company selling text-based services like to use a text-based approach when coding...

  • Stev (unregistered) in reply to M
    M:
    i did some actual testing of this one (in Java, see code below)

    And the award for TRWTF goes to...

  • Jibble (unregistered) in reply to @Deprecated
    @Deprecated:
    Wow, so many inefficiencies I don't even know where to start!

    Don't worry, Moore's law will soon take up the slack.

  • Derp (unregistered)

    And I thought MY code was bad.

  • Derp (unregistered) in reply to Alex
    Alex:
    I think a loop with said "c >= '0' and c <= '9'" would beat the RegExp performance-wise.
    foreach (char c in input)
    {
       if ((c < '0') || (c > '9'))
       {
          LogDebug("Invalid character found")
          return false;
       }
    }
    LogDebug("Everything purrrrfect")
    return true;
    

    This is correct. In fact this is about a thousand times faster than Regex.IsMatch(string, @"\d+");

  • Pero Perić (unregistered) in reply to @Deprecated
    @Deprecated:
    Wow, so many inefficiencies I don't even know where to start!
    • Rebuilds array every time it is called
    • Uses an array instead of c >= '0' and c <= '9'
    • Calls substring repeatedly in inner loops
    • Does not exit early from outer for loop
    • Using strings instead of booleans

    Ugh. Maybe the array is used in case sometime in the future, a new number is added between '4' and '5'.

    Using collection of valid chars instead of boolean expression is more maintainable approach. Judging by the method name, arbitrary set of chars can be considered valid. The article text doesn't specify the number format and we all know that there are many way to represent a number as string. Signs, decimal separators, thousands separators, scientific notation (char 'e' is perfectly valid there), special values such as infinity and NaN. Rebuilding array every time reduces performance but is not as wrong as other WTFs in that code snippet, it makes the code more copy paste frendly :P.

    There should be a international law against using non-boolean values for clearly boolean output in high level languages (C and higher despite C being considered low level these days). It's not likely the method in question would be required to return "X" (undefined) or "Z" (high impedance) in future :). Using 0/1 and Y/N is not all that can be encountered in this kind of string abuse, toss in case variation (y/n, y/N, Y/n), language variation (D/N, J/N), full words (yes/now, da/ne, ja/nein...) and you be running a freak show circus. Using ints instead of bools should be also prohibited by that law.

    Anyway, regex that passes Turkish test would suffice in this case. There is a nice example in one comment how to find illegal chars using .Net Regex class. Turkish test is important, don't skip that part.

  • ped (unregistered) in reply to Derp
    Derp:
    Alex:
    I think a loop with said "c >= '0' and c <= '9'" would beat the RegExp performance-wise.
    foreach (char c in input)
    {
       if ((c < '0') || (c > '9'))
       {
          LogDebug("Invalid character found")
          return false;
       }
    }
    LogDebug("Everything purrrrfect")
    return true;
    

    This is correct. In fact this is about a thousand times faster than Regex.IsMatch(string, @"\d+");

    So, lowest level language (looks like C to me!) is best. Again, OOP is the real WTF!

  • Todd Lewis (unregistered) in reply to TGV
    TGV:
    Hey, you know student code is not a WTF! And this can't have been written by anyone with more than a week of programming experience. Right? Please?

    Or do you hire linguistic majors for your programming?

    Hey, wait a second. I'm a "linguistic major" and I've been coding for over 30 years... and... I've... written a lot of crappy code in those years.

    Yeah, okay, I see your point.

  • Derp (unregistered) in reply to ped
    ped:
    So, lowest level language (looks like C to me!) is best. Again, OOP is the real WTF!
    There's nothing inherently wrong with OOP. It's just used improperly in about 99.9453248% of cases.
  • Stark (unregistered) in reply to @Deprecated

    Apparently, you did know where to start! :-)

    And, how to finish!

    Good one.

  • Thomas (unregistered) in reply to java.lang.Chris;
    java.lang.Chris;:
    Sometimes a regexp really is the right answer ...

    ctype_digit()

  • DoctorToxn (unregistered)

    No no no! You just don't get it! He was getting ready for when all the kids grow up and "L33T Speak" is all they can write! This guy was a really forward thinking Brillant Suuuuuuuuuupppperrrrr Geeeeeeeeennniuuuuusssss.

    validCharacters.Add("0");
    validCharacters.Add("O");
    validCharacters.Add("o");
    validCharacters.Add("1");
    validCharacters.Add("I");
    validCharacters.Add("!");
    validCharacters.Add("2");
    validCharacters.Add("3");
    validCharacters.Add("E");
    validCharacters.Add("4");
    validCharacters.Add("5");
    validCharacters.Add("S");
    validCharacters.Add("6");
    validCharacters.Add("7");
    validCharacters.Add("T");
    validCharacters.Add("8");
    validCharacters.Add("B");
    validCharacters.Add("9");
    
  • Sayer (unregistered) in reply to DoctorToxn
    DoctorToxn:
    No no no! You just don't get it! He was getting ready for when all the kids grow up and "L33T Speak" is all they can write! This guy was a really forward thinking Brillant Suuuuuuuuuupppperrrrr Geeeeeeeeennniuuuuusssss.
    validCharacters.Add("0");
    validCharacters.Add("O");
    validCharacters.Add("o");
    validCharacters.Add("1");
    validCharacters.Add("I");
    validCharacters.Add("!");
    validCharacters.Add("2");
    validCharacters.Add("3");
    validCharacters.Add("E");
    validCharacters.Add("4");
    validCharacters.Add("5");
    validCharacters.Add("S");
    validCharacters.Add("6");
    validCharacters.Add("7");
    validCharacters.Add("T");
    validCharacters.Add("8");
    validCharacters.Add("B");
    validCharacters.Add("9");
    

    I get the joke but does "L33T Speak" even exist outside of ridicule anymore?

    persto: too fast to check splelign

  • (cs) in reply to Alex
    Alex:
    ... if ((c < '0') || (c > '9')) ...
    That only works if your character set happens to put the digits 0-9 in consecutive code points.

    To be fair, this is true for pretty much everything, but trying to do the same logic with 'a' thru 'z' could fail horribly if EBCDIC got involved...

  • DigCamara (unregistered) in reply to @Deprecated

    Damn those futurians and their weird maths!

  • Peter Orbers (unregistered) in reply to @Deprecated
    • Uses an array instead of c >= '0' and c <= '9'

    This depends on an arbitrary sort order.

  • Double-Posting Guy (unregistered)

    At what time does Alex post articles on this so-called "daily" site?

  • Double-Posting Guy (unregistered)

    At what time does Alex post articles on this so-called "daily" site?

  • Christian (unregistered)

    There is a wheel that once, a long and long forgotten time ago, was invented and they called it Regex. It was a good wheel and it rolls on to this very day. Programmers like these shun this wheel though as complicated and slow and rather work with wheels that are cut in two, have not less than 3 not more than 5 edges and preferable an axle attached to more than one of these edges. If they didn't invent it, it can't be good.

Leave a comment on “Stringy Sting Verification”

Log In or post as a guest

Replying to comment #:

« Return to Article