• Anon (unregistered)

    On embedded systems without a file system...

  • frist (unregistered)

    Looks like a pretty optimised piece of code to me. Why should I trust a compiler to unroll my loop?

  • A. Coward (unregistered)

    Who needs to learn compex math when you have the power of if at your disposal?

  • L (unregistered)

    Shouldn't it be 10 - (39 mod 10) ?

  • Anomynous Coward (unregistered) in reply to L
    L:
    Shouldn't it be 10 - (39 mod 10) ?

    Alex clearly learned a lesson from this WTF and unrolled the (39 mod 10) operation inline.

    Captcha: plaga, the idea of excessive loop unrolling was plagarised?

  • frits (cs)

    There seems to be a few semicolons missing.

  • Thg (unregistered)

    The lack of a filesystem is not the limiting factor. It's that there is no math library available once printed to a barcode.

  • dgushurst (unregistered)

    AWTF: "As for the most wondrous thing about this program? The coder took special care to find out exactly what ZIP code ranges aren't used by the postal service, so as to avoid unnecessary coding for those ranges."

    Looks to me like this "code" goes to extra pains to test every zipcode against every range. Otherwise they would have used an if-else-if construct.

  • ThomasP (unregistered) in reply to frits
    frits:
    There seems to be a few semicolons missing.

    I'm betting that someone had the ingenious idea to move all of their systems to a web platform and they hired someone's teenage kid who knew some javascript to write it.

  • frits (cs)

    Some coders should have their clipboard disabled.

  • I really need to find my logon info again (unregistered)

    Boss: Postal code validation? Oh no! What do we do?! I've got a team of crack developers, who can do this in 20 minutes, or..... HELP! BOSS'S NEPHEW!

    Offscreen Voice: Someone needs my help! And it uses a com-pew-tor! I know what they are, I read a book once! This sounds like a job for <BOOMING VOICE>Boss's Neeeeeeephewwwwww!</BOOMING VOICE>.

    Narrator: In today's episode, we find Boss's Nephew in charge of a hamster, a jar of vaseline, and a computer. His task: Ensure we have valid postal codes. Let's see how he can screw it up!

    [8 hours later]

    Boss's Nephew: "Well, the hamster's dead, he drowned in the vaseline, I can't find my shoes, and I set a horse on fire, but I think the postal-code checking thing is complete!"

    Boss: "Great job! You get a bonus! Thanks for being so awesome! Say hi to my sister!"

    Boss's Nephew: "Thanks Uncle-Boss!"

    Other developers: sobbing

    [fade to black]

  • Chris Haas (unregistered)

    I'd prefer a giant switch block

  • @Deprecated (unregistered) in reply to Anon
    Anon:
    On embedded systems without a file system...

    you would recieve a sound thumping about the ears for wasting precious flash eeprom on code like this.

    Either that, or Alex needs to improve the "Prove you're not a bot" test.

  • Quirkafleeg (unregistered)
    There's also a check digit on the bar code, which is calculated by adding up all the digits of the barcode, modding the result by 10, and then subtracting from 10.
    Fail. If sum (digits) % 10 == 0, the result of the calculation is 10.
  • Jim (unregistered)

    I was just sick in my mouth a little.

  • Richard (unregistered)

    A very impressive piece of coding. The programmer was aware that division and converting numbers to strings (and v.v.) for string manipulation are both more expensive operations than comparison and addition, so he/she took steps to avoid them, at the price of a little extra maintenance. Of course, the code could have been optimized further by eliminating the "3 + 4 + 2" sections -- that's a high price to pay for self-documenting code.

  • anon (unregistered)

    Surely this is a for for...recursion!

  • BBT (unregistered)

    So the WTF is that he didn't use a for-case, right?

  • Quirkafleeg (unregistered) in reply to Richard
    Richard:
    A very impressive piece of coding. The programmer was aware that division and converting numbers to strings (and v.v.) for string manipulation are both more expensive operations than comparison and addition, so he/she took steps to avoid them, at the price of a little extra maintenance. Of course, the code could have been optimized further by eliminating the "3 + 4 + 2" sections -- that's a high price to pay for self-documenting code.
    All of those comparisons, all of those if statements, and (apparently) not an else to be seen. It seems to me that that cancels out the optimisations.

    Not that adding elses would help.

  • BentFranklin (unregistered)

    How would string manipulation functions help calculate the check bit?

  • Gatra (unregistered) in reply to BBT
    So the WTF is that he didn't use a for-case, right?
    Please be a troll
  • AndrewH (unregistered) in reply to A. Coward
    A. Coward:
    Who needs to learn compex math when you have the power of if at your disposal?

    Or even simple math.

  • 4merK0d34 (cs)

    Should have used a look up table.

  • ClaudeSuck.de (unregistered)

    I wonder if we can find more Counter math in his code...

  • Todd Lewis (unregistered) in reply to 4merK0d34
    4merK0d34:
    Should have used a look up table.
    ...in XML.
  • Yaos (cs)

    The code is pretty scary, what happens if the value of 1 changes in the future to 2 or even 3? It would be much faster and easier and secure to create an access database, in one table you have every possible barcode and in another table you have every possible address and then a 3rd table that is used to join the address to the barcode.

    As a bonus, this ensures you will always only create barcodes for addresses that exist which will save the post office money because they won't try to deliver to an address that does not exist.

  • Offtopic (unregistered)

    Can anyone explain the advantage ou using 10-(n mod 10) over simply using n mod 10?

    I've also seem a lot of check digits based on (n mod 11) that end up mapping two results to the same check digit. Never understood why.

  • yummy (unregistered)

    Seems that they are missing the 'zzzipcode' variable, or perhaps the 'zzzzipcode'

  • Marc B (unregistered)

    It is possible that the code is a port from dBase III. That damned language didn't have a mod function (or many math functions at all).

    There was still a much easier way of calculating mod. And it was surprisingly strong in string manipulation.

  • Studley (unregistered)

    comment = comment + "w" + "t" + "f";

  • Tanuki (unregistered)

    The saddest part is, that what idiots manage to figure out and utilize very well is the search and replace tool of their IDE which in turn makes abominations like this possible.

  • Anon (unregistered)

    This WTF is too sick to comment. o_O

  • Wonko The Sane (unregistered)

    How I would do it if there was no string slicing or Mod command....

    C=0; if (Zcode=>10000 and Zcode<=19999) { Zcode=Zcode-10000; C=1; } If (Zcode=>20000 and Zcode<=29999) { Zcode=Zcode-20000; C=2; } ' Repeat for 30000,40000,50000,60000,70000,80000 & 90000 ... If (C>10) then {C=C-10;} ' Simple Mod 10 If (Zcode=>1000 and Zcode<=1999) { Zcode=Zcode-1000; C=C+1; } If (Zcode=>2000 and Zcode<=2999) { Zcode=Zcode-2000; C=C+2; } ' Repeat for 3000,4000,5000,6000,7000,8000 & 9000 ... If (C>10) then {C=C-10;} ' Simple Mod 10 If (Zcode=>100 and Zcode<=199) { Zcode=Zcode-100; C=C+1; } If (Zcode=>200 and Zcode<=299) { Zcode=Zcode-200; C=C+2; } ' Repeat for 300,400,500,600,700,800 & 900 ... If (C>10) then {C=C-10;} ' Simple Mod 10 If (Zcode=>10 and Zcode<=19) { Zcode=Zcode-10; C=C+1; } If (Zcode=>20 and Zcode<=29) { Zcode=Zcode-20; C=C+2; } ' Repeat for 30,40,50,60,70,80 & 90 ... If (C>10) then {C=C-10;} ' Simple Mod 10 ' Zcode should be between 0 and 9 so just add it on... C=C+Zcode; If (C>10) then {C=C-10;} ' Simple Mod 10 CDigit=10-C; if (CDigit>9) {CDigit=0;}

  • Unrolled Loop (unregistered)

    The goggles, they do nothing!

    CAPTCHA: veniam - I'll have a bottle of 1856 veniam - would you like to try some?

  • frits (cs) in reply to Wonko The Sane

    Are you serious?

    See below for a simple mod if mod didn't exist.

    //Works for languages that "round down" the result of an integer division
    //Base cannot be 0
    uint Modulus(uint value,uint base)
    {    
        return value - ((value/base) * base);
        
    }
  • Niraj (unregistered)

    frankly i have no words to describe this WTF ...

    oh ... i do have some words ... Genius ... pure genius !!!

    now again i have run out of words :((

  • RandomUser423678 (unregistered) in reply to Quirkafleeg
    Quirkafleeg:
    There's also a check digit on the bar code, which is calculated by adding up all the digits of the barcode, modding the result by 10, and then subtracting from 10.
    Fail. If sum (digits) % 10 == 0, the result of the calculation is 10.
    The purpose of the algo is to generate the check digit such that the sum of all the digits, including the check digit, is a multiple of 10. A valid fix to the problem you point out is to do another modulo-10 after taking the difference. There are other approaches with the same result.
  • Anonymous (unregistered) in reply to Niraj
    Comment held for moderation.
  • Tuna-Fish (unregistered) in reply to Wonko The Sane
    Wonko The Sane:
    How I would do it if there was no string slicing or Mod command.... -- Snip 50 lines of horror, that included "repeat this 10 times" statements. --
    replacement for slicing strings: C = 0 for (i: 0..4): C = C + Zcode / 10^i

    replacement for positive mod: i = i - ((i/10) *10)

  • Spoe (unregistered) in reply to Quirkafleeg
    Quirkafleeg:
    There's also a check digit on the bar code, which is calculated by adding up all the digits of the barcode, modding the result by 10, and then subtracting from 10.
    Fail. If sum (digits) % 10 == 0, the result of the calculation is 10.

    The CASS Technical Guide defines the check digit thus:

    The delivery point check digit (or correction character) is a number that is added to the sum of the other digits in the delivery point barcode (DPBC) to yield a number that is a multiple of ten.

    So sounds more like the check digit is: (10 - (sum % 10)) % 10.

  • Patrick (unregistered)

    They could halve the speed of that code by wrapping it in another if that splits in the middle. Ooh, or better yet, keep nesting that in both sides. It's a B-Tree of ifs! Brilliant!

  • Quirkafleeg (unregistered) in reply to Wonko The Sane
    Wonko The Sane:
    How I would do it if there was no string slicing or Mod command....
    C=0;
    if (Zcode=>10000 and Zcode<=19999) {
       Zcode=Zcode-10000;
       C=1;
    }
    If (Zcode=>20000 and Zcode<=29999) {
       Zcode=Zcode-20000;
       C=2;
    }
    ' Repeat for 30000,40000,50000,60000,70000,80000 & 90000
    ...
    If (C>10) then {C=C-10;} ' Simple Mod 10
    Fails for C≥20.
    C = C - 10 * INT (C / 10)
    If (Zcode=>1000 and Zcode<=1999) {
       Zcode=Zcode-1000;
       C=C+1;
    }
    C = 0
    WHILE Zcode
      D = INT (Zcode / 10)
      C = C + Zcode - D * 10
      Zcode = D
    ENDWHILE
  • Zylon (cs)

    Pathetic. The enterprisey way to do this would be to have an SQL database containing the correct check digit for every possible postal code.

  • frits (cs) in reply to Anon
    Anon:
    On embedded systems without a file system...

    Embedded systems is the new "Frist!"

  • delta224 (cs)

    I wonder if the person was getting paid by LOC.

  • The Optimizator (unregistered)

    int chkdgt(int zipcode) { switch (zipcode) { case 10000: return 9; case 10001: return 8; case 10002: return 7; case 10003: return 6; case 10004: return 5; case 10005: return 4; case 10006: return 3; case 10007: return 2; case 10008: return 1; case 10009: return 10; case 10010: return 8; case 10011: return 7; case 10012: return 6; case 10013: return 5; case 10014: return 4; case 10015: return 3; case 10016: return 2; case 10017: return 1; case 10018: return 10; case 10019: return 9; case 10020: return 7; case 10021: return 6; case 10022: return 5; case 10023: return 4; case 10024: return 3; case 10025: return 2; case 10026: return 1; case 10027: return 10; case 10028: return 9; case 10029: return 8; case 10030: return 6; case 10031: return 5; case 10032: return 4; case 10033: return 3; case 10034: return 2; case 10035: return 1; case 10036: return 10; case 10037: return 9; case 10038: return 8; case 10039: return 7; case 10040: return 5; case 10041: return 4; case 10042: return 3; case 10043: return 2; case 10044: return 1; case 10045: return 10; case 10046: return 9; case 10047: return 8; case 10048: return 7; case 10049: return 6; case 10050: return 4; case 10051: return 3; case 10052: return 2; case 10053: return 1; case 10054: return 10; case 10055: return 9; case 10056: return 8; case 10057: return 7; case 10058: return 6; case 10059: return 5; case 10060: return 3; case 10061: return 2; case 10062: return 1; case 10063: return 10; case 10064: return 9; case 10065: return 8; case 10066: return 7; case 10067: return 6; case 10068: return 5; case 10069: return 4; case 10070: return 2; case 10071: return 1; case 10072: return 10; case 10073: return 9; case 10074: return 8; case 10075: return 7; case 10076: return 6; case 10077: return 5; case 10078: return 4; case 10079: return 3; case 10080: return 1; case 10081: return 10; case 10082: return 9; case 10083: return 8; case 10084: return 7; case 10085: return 6; case 10086: return 5; case 10087: return 4; case 10088: return 3; case 10089: return 2; case 10090: return 10; case 10091: return 9; case 10092: return 8; case 10093: return 7; case 10094: return 6; case 10095: return 5; case 10096: return 4; case 10097: return 3; case 10098: return 2; case 10099: return 1;

    ... [SNIP] ...

    	case 99900:
    		return 3;
    	case 99901:
    		return 2;
    	case 99902:
    		return 1;
    	case 99903:
    		return 10;
    	case 99904:
    		return 9;
    	case 99905:
    		return 8;
    	case 99906:
    		return 7;
    	case 99907:
    		return 6;
    	case 99908:
    		return 5;
    	case 99909:
    		return 4;
    	case 99910:
    		return 2;
    	case 99911:
    		return 1;
    	case 99912:
    		return 10;
    	case 99913:
    		return 9;
    	case 99914:
    		return 8;
    	case 99915:
    		return 7;
    	case 99916:
    		return 6;
    	case 99917:
    		return 5;
    	case 99918:
    		return 4;
    	case 99919:
    		return 3;
    	case 99920:
    		return 1;
    	case 99921:
    		return 10;
    	case 99922:
    		return 9;
    	case 99923:
    		return 8;
    	case 99924:
    		return 7;
    	case 99925:
    		return 6;
    	case 99926:
    		return 5;
    	case 99927:
    		return 4;
    	case 99928:
    		return 3;
    	case 99929:
    		return 2;
    	case 99930:
    		return 10;
    	case 99931:
    		return 9;
    	case 99932:
    		return 8;
    	case 99933:
    		return 7;
    	case 99934:
    		return 6;
    	case 99935:
    		return 5;
    	case 99936:
    		return 4;
    	case 99937:
    		return 3;
    	case 99938:
    		return 2;
    	case 99939:
    		return 1;
    	case 99940:
    		return 9;
    	case 99941:
    		return 8;
    	case 99942:
    		return 7;
    	case 99943:
    		return 6;
    	case 99944:
    		return 5;
    	case 99945:
    		return 4;
    	case 99946:
    		return 3;
    	case 99947:
    		return 2;
    	case 99948:
    		return 1;
    	case 99949:
    		return 10;
    	case 99950:
    		return 8;
    	case 99951:
    		return 7;
    	case 99952:
    		return 6;
    	case 99953:
    		return 5;
    	case 99954:
    		return 4;
    	case 99955:
    		return 3;
    	case 99956:
    		return 2;
    	case 99957:
    		return 1;
    	case 99958:
    		return 10;
    	case 99959:
    		return 9;
    	case 99960:
    		return 7;
    	case 99961:
    		return 6;
    	case 99962:
    		return 5;
    	case 99963:
    		return 4;
    	case 99964:
    		return 3;
    	case 99965:
    		return 2;
    	case 99966:
    		return 1;
    	case 99967:
    		return 10;
    	case 99968:
    		return 9;
    	case 99969:
    		return 8;
    	case 99970:
    		return 6;
    	case 99971:
    		return 5;
    	case 99972:
    		return 4;
    	case 99973:
    		return 3;
    	case 99974:
    		return 2;
    	case 99975:
    		return 1;
    	case 99976:
    		return 10;
    	case 99977:
    		return 9;
    	case 99978:
    		return 8;
    	case 99979:
    		return 7;
    	case 99980:
    		return 5;
    	case 99981:
    		return 4;
    	case 99982:
    		return 3;
    	case 99983:
    		return 2;
    	case 99984:
    		return 1;
    	case 99985:
    		return 10;
    	case 99986:
    		return 9;
    	case 99987:
    		return 8;
    	case 99988:
    		return 7;
    	case 99989:
    		return 6;
    	case 99990:
    		return 4;
    	case 99991:
    		return 3;
    	case 99992:
    		return 2;
    	case 99993:
    		return 1;
    	case 99994:
    		return 10;
    	case 99995:
    		return 9;
    	case 99996:
    		return 8;
    	case 99997:
    		return 7;
    	case 99998:
    		return 6;
    	default:
    		return FILE_NOT_FOUND;
    }
    

    }

  • SR (unregistered) in reply to frits
    frits:
    Embedded systems is the new "Frist!"

    I agree completely. It's very tiresome.

    (I'm not terribly proud that my first comment on this WTF is a grumpy one.)

  • Ken B. (unregistered) in reply to Offtopic
    Offtopic:
    Can anyone explain the advantage ou using 10-(n mod 10) over simply using n mod 10?
    Because, regardless of the length of the input string, the sum mod 10 (including any check digits) is always zero.
  • frits (cs) in reply to The Optimizator

    No no, you're doing it wrong.

    
    Dictionary<int,int>CheckDigits = new Dictionary<int,int>();
    int digit = 10;
    for(int i = 10000;i<99999;i++)
    {
        if(digit <1)
        {
            digit = 10;
        }
        CheckDigits.Add(i,--digit);
        
    }
    
    
  • Ken B. (unregistered) in reply to Zylon
    Zylon:
    Pathetic. The enterprisey way to do this would be to have an SQL database containing the correct check digit for every possible postal code.
    ... which is kept on a computer at corporate HQ, so that any changes to the definition of "mod 10" can be rolled out quickly.

    Of course, the database iwll be behind a firewall, inside the VPN, to prevent "hackers" from getting access to the trade secrets kept in the database.

Leave a comment on “Check Digit Check”

Log In or post as a guest

Replying to comment #:

« Return to Article