- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Plot twist: the uint is a 32 bit representation of the PIN in either BCD, packed BCD, ASCII or EBCDIC.
Admin
In C, 0410 and 410 ARE numerically different values, likely on some other programming languages too :)
Admin
Semantically backwards, although the end point is valid.... It is not a PIN (which by definition is Numeric - hence the N), but rather it is a PII which is composed of digits....
Addendum 2022-09-29 06:52: Additionally 0410 is equal to 264 is equal to 0x108 is equal to CCLXIV
So any of those inputs should be accepted....(if it was truely a number)
Admin
Well, no. Because Dutch and German have two words: nummer/Nummer, which is a non-arithmetic number, and getal/Zahl, which is arithmetic. The distinction is almost, but not quite, the same as that between ordinal and cardinal numbers. Crucially, though, English does not have that distinction. And therefore, in English, you can have something which is a number, but is also not numeric.
Admin
Obligatory: TRWTF is what "via behind a PIN" means.
I agree with the earlier comment that if leading zeroes are significant, it's a numeric passcode rather than a PIN. But even then, one could just add 10**n to an n-digit code. A 31- or 32-bit integer is larger enough to hold up to 9-digit codes like that.
Admin
As a Dutchman, I approve of this message.
Another titbit: English/American, the expression "You have my digits?" means "Do you have my phonenumber? (which is commonly numeric) and not "Do you have my fingers".
Admin
If you enforce that the user enters 4 digits, then 410 simply won't occur. Still a weird type, though. Perhaps someone replaced char[4] by uint32, because the first one is a pointer in calls? That's one way to C it, at least.
Admin
Perhaps there is some hidden logic that left pads the number with '0's out to a 4 character string, so if the user enters 410, it will still try to validate against 0410.
Admin
Technically, there could even be additional layers of WTF on top of this.
For example the PIN check could have been made between a text-typed input with the stored integer by using the implicit type coercion of some programming languages: http://phpsadness.com/sad/47
Also, a 4-character PIN is one thing, but if there could be some nice additional WTFs when comparing very large numbers with overflows, losses of precision, etc.
Comparison is quite a minefield of a topic.
Admin
If a pin is numeric, I'm interested in the average value.
Admin
Sorry but WTF with this article? I think there's absolutely nothing wrong with PIN being uint. As long as we agree on the PIN length, 410 would mean 0410, no ambiguities here. (And if we decided to store different-length PINS in our database we would be crazy). So uint is perfectly fine. But char[4] is not - this is the root of all evil, because that's where PINS={'0410', ' 410', 'XXXX', 'NOTP'} come from.
Admin
I hate you.
Admin
Is this actually a WTF? If the user enters 0410 into the device, and it parses it as a number, it will match 410 correctly.
Does the device allow you to type less than 4 digits, and do they require that 410 be treated differently from 0410? That would indeed be a problem.
Admin
Yes it is. Because the type PIN does not correspond to the type uint. Nor does it correspond to the type string.
Let's rename the type PurpleMonkeyDishwasher. That removes any assumed numerical or other semantics, falsely based on the name.
Now, you can store and retrieve a PurpleMonkeyDishwasher using any backing field you like (I would suggest a string, obviously), but you can only store to the backing field if the semantics of the input are correct. Which in this case would logically be validated via a regexp.
The getter here clearly elides perfectly valid PurpleMonkeyDishwashers ... so, it's borked.
Admin
Unless you have just been involved in an industrial accident, in which case the question may be ambiguous.
Admin
"in English, you can have something which is a number, but is also not numeric."
All languages have that - in English, sixty-one is an example.
If you meant the other way around, a string made up of numerals is not a number in English, though the word is often abused. We really ought to say pi code, telephone code, etc.
Admin
I'm confused, the N in PIN standard for number, so yes, 0123 is the same as is 123.
The reason is simple, leading zeros are just that, a formatting choice. In a set of digits [0..9] there is no other digit that could replace the 0 without changing the value of 123. So uint is the second best choice, after int.
Admin
Who would ever start their PIN with a 0? Don't do that! Slap! Slap! Whap!
Admin
0123 and 123 are not the same. This is open to interpretation.
Simple example: 017 vs 17. By many conventions 017 is Octal 17; or base 8. 017 = octal 17 = 8 + 7 = 15.
To use your example, 0123: 0123 = octal 123 = 8 squared + (2 x 8) + 3 = 64 +16 + 3 = 83.
This can be enormously problematic when referring to IPv4 addresses in dotted-quad notation.
Admin
I had huge arguments with my colleagues years ago about how to store a CPF (brazilian SSN). It is a 11 character numeric string. Some of my coworkers wanted to store them as a numeric type. I argued that it would add more complexity, since the application would have to fill the leading zeroes, among other things.
Admin
This "just works" only if you're restricted to a set number of digits, and you can rely on the calling code ensuring the correct number of digits have been entered. This makes it a poor choice and rather flaky.
If you think of the PIN as a sequence of digits, rather than a single number, you'll likely end up with a much more stable implementation that can work with any changes to the requirements (or at least, with very little effort in the future). E.g. if the PIN is allowed to contain letters or other symbols (OK, no longer a number, but still a "PIN" for all intensive porpoises - I have no time for pedants), or use a variable number of digits (where 0123 is not the same as 00123).
Admin
"Call me when you find me, do you..." DOH !
Admin
It would depend on what a PIN actually is in practice on this device. Every bank account I’ve ever had with a PIN has had it as a 4-digit sequence, which EFFECTIVELY means an integer from 0 to 9999 — the sequence "0410" converts to 410 for storage, but when retrieved it gets formatted back to "0410". There’s no data loss and the conversions are simple: parse to integer to store, pad to 4 digits (and optionally read off the digits 1 by 1) to retrieve. I challenge you to give even a single valid PIN under that scheme which does not store as a unique value as an unsigned integer, or for which the stored unsigned integer value does not seamlessly convert back into the original PIN. There is only a practical difference between "0410" and 410 if the pin is really a password, not a PIN — in which case one of the issues involved is that the people who wrote the documentation don’t know what a PIN is.
Admin
"Tina" here. I have never actually seen the particular UI, however, in other places on that device, other PINs are variable-length. FWIW, I believe my bank allows you to increas e the PIN length ...
Admin
Challenge accepted.
My bank gave the option to switch from a four-digit PIN to an (optional) 5-digit pin. Lazy as I am, I went from 1234 to 01234. Now, if a hacker would enter 1234 (which is also still a valid PIN), it would validate erronously.
Sidenote: you should not store a PIN. You should store the hash of that PIN. that's TRWTF
Admin
I am not sure what your are talking about, I was talking about numbers not how some language (like C, C++) represent numeric literals. So even if you consider that jump off-topic, the code is clearly C# and there is no leading 0 for octal numeric literals.
Admin
True.
But I think I would rather rely on correct typing and persistence, rather than "it's what the documentation says."
Admin
Sidenote to sidenote:
I like that thinking, and I agree. But it doesn't go far enough.
The first problem I see is that, if the requirement "store PIN as a hash" is sent to a C# programmer (eg me), the first implementation is almost bound to be GetHash(). Which ... I suppose you could override it, but it's likely to be wrong, because collisions.
The second problem is that you probably want to salt the hash somehow. At which point we get into basic cryptography, a field in which I am supremely ignorant. (One amongst many.)
Then again, overriding GetHash() for our specific type, PurpleMonkeyDishwasher, is probably secure enough. So long as the attacker doesn't have access to the C# on the server (in which case they would be able to disassemble the algorithm used), they're no better off at guessing the hashing mechanism.
Admin
In C# you would use one of the Hash-Providers which are part of the framework since 1.0, like SHA256 ;-) And yes, you should always salt hashes, unsalted once are easily brute forced, especially when you have only 10,000 different results.
Admin
Ann on a Mouse (unregistered) wrote "It would depend on what a PIN actually is in practice on this device. Every bank account I’ve ever had with a PIN has had it as a 4-digit sequence, which EFFECTIVELY means an integer from 0 to 9999"
You can't be blamed for thinking that, because banks are absolutely TERRIBLE about allowing only 4 digits, but PINs are by standard 4 - 12 digits long, and leading zeroes are absolutely significant. I've been out of the business for a long time so I may have the wrong standard, but I believe this is be covered in ISO 9564/ANSI X9.8.
Admin
Good point & interesting observation, but you swapped the definitions/their meanings in your explanation. "nummer/Nummer" denotes an index in a sequence (123 could be the 321th number), whereas "getal/Zahl" refers to the number in isolation (wherever 123 appears in some sequence, it's still the number 123). The main problem of this CODESOD is that "cijfer/Ziffer" is interpreted numerically instead of just taking it for what it is, namely some glyph (which has a unicode/ASCII/... number :-).
Admin
Addendum 2022-10-03 14:44:
I dislike this forum software, how it handles quotes and it's lack of a preview feature.
Also, why can I only describe my desired revision through a tiny slit in the browser?
Admin
Are they guaranteed to always be 4 digit numerical passwords (crucially not "numbers", because then 0410 and 410 should in fact be considered the same thing) though? It's often the case with these. And then it's honestly FINE. It's a bit hacky and might cause trouble down the line, but it's FINE. You won't have a collision on 0410 vs 410, because 410 by itself is simply not an option, and neither is any other sub-4 digit code, so using them to represent codes with leading zeroes is FINE.