- 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
If it's not a string, don't put letters in it.
Admin
the true wtf in this (and every other) case is the halfassed endianness of the MS GUID implementation
Admin
You can't complain about the GUID being converted to a string without knowing how it's used. The article mentions Active Directory - I have no idea whether AD has search APIs that take a .NET Guid object directly, but if the code is searching with an LDAP filter string then the GUID obviously needs to be stringified in the format that it appears in in the directory.
Admin
TRWTF is the article trying to tell us what TRWTF is.
Admin
Surely everything is a number when you're working with computers?
GUIDs are blobs of information, not numbers. We should not process them as numbers. We should not pass them around as numbers.
Admin
Converting the Guid to a byte[] is what makes this a WTF - if the coder had called ToString().Replace("-", "") (which would have done exactly the same thing) I think we might all have understood it to be a naive approach. However, BitConverter exists for making explicit byte-to-string conversions (e.g. hex representations of hashes), so the use of it and then specifically interfering with the output is very wrong.
Can't deny that sometimes you do need to work with GUIDs or UUIDs as strings though, as others said it may be an API requirement.
Admin
... and to make this even better, according to the signature, this method does not return anything. :-)
Admin
Another thought: What are you doing with these GUIDs that means the format is significant? Hopefully not showing them to the user. If you're putting them back in AD, say, then it will either take a GUID directly, making this whole post pointless, or it will use Guid.Parse which follows the half-mantra "be liberal in what you accept", i.e. it doesn't matter how many dashes there are as long as it contains a GUID's worth of hexadecimal.
Anyway what's with "incompotible" and "hexidecimal"?
Admin
The OP should at least know fundamental .NET classes.... https://msdn.microsoft.com/en-us/library/system.bitconverter(v=vs.110).aspx
Admin
Sadly some DBs do not support UUIDs and some analytics packages haven't grasped the concept of a 64bit integer. The former means we have to convert the UUID to a CHAR. The latter, words fail me.
I never thought of a UUID as a blob of information. I kind of thought of them as a 128 bit integer
Admin
Reminds me of working with OIM's API.
In Oracle Internet Manager, there are two distinct APIs: com.thortech.xl.* oracle.iam.*
Those two are not compatible. You can't just convert a com.thortech user to an oracle.iam user or vice-versa. com.thortech is mostly deprecated but the oracle.iam one doesn't support all features. So, when I needed to implement functions, it wasn't too uncommon to run the relevant ldap query twice to obtain objects of both oracle.iam and com.thortech. The parameters to make them work were more often then not of different types so obtaining a byte[] and a String and an ldap object of the same thing?... par for the course.
Admin
I knew a Java programmer who in an attempt to set Dates as parameters for a CallableStatement, insisted upon converting them to Strings in Oracle's default date format and then back to Dates. Because the original Dates were created from Strings in a different format.
IIRC the actual problem was that he was using java.lang.Dates and needed java.sql.Dates, which was the first thing I suggested, along with trying to explain that even if they're created from a datestring, Date objects do not store a format.
Admin
"I never thought of a UUID as a blob of information. I kind of thought of them as a 128 bit integer"
They are 128 bits of data. They aren't really integers, you don't do any arithmetic operations on them.
Admin
Next week on TDWTF: 128 bits? holy crap, that's a big number. I don't remember how many bits fit into this type, I'd better make it a float just to be safe, cuz I know floats can get huge.
Admin
The worst misuse of GUIDs that I have seen was when this guy's blog site used them for his articles. The URL was literally sitename.com/${GUID} with no extra unused characters hanging along with the article title or whatever. I don't even think the URL had the date in it. So any random article link you got was just a vomit of hexadecimal, with no clue as to what you were going to see when you got there.
What made it so bad was that this was a Macintosh fanboy website! I think it was Daring Fireball. I checked just now and if that was the site, it's long since been ported to a much more sane CMS. I don't know why it was using GUIDs back then, but it was Just Wrong for an Apple/Macintosh fanboy website to use something as Microsoft-centric as GUIDs.
Admin
You wouldn't believe (er, well, being here, I guess you would at that...) how many people have trouble grasping that IP-addresses are numbers, too. Especially if you start using subnets other than /24's (and don't even let me get started on IPv6).
Makes for some cool party tricks (er... depending on the crowd :P ) like going to http://1244819064 instead of http://thedailywtf.com
Admin
I hope you are being sarcastic.
Admin
"GUIDs are not strings. They are numbers."
Neither. They are identities. To check identity, representation should not matter, yes. But when dealing with input that contains identities in serialized form, deserialization is still required.
Although I'd expect an implementation to understand "new UUID(serialization)" for the most common forms of serialization for a specific kind of UUID. There shouldn't be a need to fiddle with dashes or case.
Admin
It's important to note that GUID strings are not displayed in byte order. This is correct according to RFC4122 (not a quirk of the Microsoft implementation).
If you take the GUID 35918bc9-196d-40ea-9779-889d79b753f0 and display it in lowercase hex byte order, the result is not "35918bc9196d40ea9779889d79b753f0" but rather "c98b91356d19ea409779889d79b753f0".
The question remains of "why do you want a GUID displayed in byte order"? Of course, we don't know, but I have had to interface with external systems that required GUIDs as strings in byte order. Stupid, IMO, but often something outside of your control.
Also, BitConverter does insert dashes, which I have always found annoying.
https://dotnetfiddle.net/yyOe6e
Admin
TRWTF is assuming that there is never a valid reason to process a guid as a string
Admin
What, pray tell, does 'incompotable' mean? You can't make compote with it?
Admin
To be fair, that's how Oracle converts its dates too. You want to convert a DATE into a TIMESTAMP? Oracle will convert the former to a string with the default date format, and parse it with the default timestamp format. I discovered this awfulness when Oracle puked me an error one some day where I had changed the current session's default date format to something more readable, while leaving the timestamp format unaltered.
Addendum 2017-04-24 12:32: If you're not in the IHOC yet, I'd gladly be your sponsor.
Admin
17th
Admin
Reminds me of a job I worked at. They didn't want to use a real GUID library because "GUIDs aren't guaranteed to be unique if you use them enough times", so they rolled their own GUID library. It was a 64 bit integer... starting at 0... and then incrementing by one each time an entity was created. When asked what happens when the value rolled over the response was "we don't create that many entities". When asked what happens when they try to merge 2 different datastores using their own counter the response was "uh... we haven't had to do that yet" And yes, eventually they had to merge datastores, and it was much wailing and gnashing of teeth.
Admin
Kudos to Microsoft for declaring their identifiers as "Globally" unique rather than "Universally" unique. Personally, I think the progress we can make is limited until we start using identifiers that will be unique across the multiverse. MUUIDs FTW.
Admin
Welcome to TDWTF. PROTIP: Remy's articles should be read in raw HTML format for completeness.
Admin
Real programmers pass GUIDs around any freaking way they please. Real programmers convert GUID numbers to strings, ROT-13 the strings for security, and then UUENCODE them for transmission.
Admin
I work with Minecraft. Mishandling UUIDs is extremely common.
TRWTF is why I'm still involved with Minecraft, though.
Addendum 2017-04-25 04:09:
I relate to this story far too much.
Admin
I'm fairly sure this guy did not know that, and he wasn't using this string format to create the correct Date type or anything.
He was just convinced, and would not be convinced otherwise, that a java.lang.Date created by parsing "2016-01-01" was different from a java.lang.Date created by parsing "01-APR-2016".
Addendum 2017-04-25 10:17: Whoops, that should be java.util.Date.
Admin
"They didn't want to use a real GUID library because "GUIDs aren't guaranteed to be unique if you use them enough times", so they rolled their own GUID library. "
If you give every person on earth a camera, and they start taking photos, one a second, and give each photo a random GUID, then chances are that in about 500 years you might have two photos with the same GUID. Or maybe not.
If a function comparing random GUIDs that were created independently claims that the GUIDs match, then it is much much more likely that a cosmic ray flipped a bit in your computer, changing the result of the comparison function from "false" to "true", than having two identical GUIDs.
Admin
"He was just convinced, and would not be convinced otherwise, that a java.lang.Date created by parsing "2016-01-01" was different from a java.lang.Date created by parsing "01-APR-2016".
I don't know enough about Java; in MacOS / iOS the type called "date" is actually a point in time, including hours, minutes, seconds etc., and it could be that parsing one string adds the time bits from your locale, and parsing the other string uses UTC. That would be a rubbish API, but rubbish APIs matter. Obviously it shouldn't take you more than five minutes to write a test for that. What is definitely not contained in a date is any timezone information, locale information, parsing format information etc. It's just a point in time.
Admin
"Real programmers pass GUIDs around any freaking way they please. Real programmers convert GUID numbers to strings, ROT-13 the strings for security, and then UUENCODE them for transmission"
I use ROT-13 twice to improve readability. Readability is important :-)
Admin
Some programmers around here have a habit of creating a bunch of void GetXXX methods that load/retrieve/calculate some value and assign that to some global variable.
Admin
ITT: People who don't actually understand UUIDs and their string representation.
From RFC 4122:
Admin
In the absence of explicit application or presentation protocol specification to the contrary, a UUID is encoded as a 128-bit object, as follows:
The fields are encoded as 16 octets, with the sizes and order of the fields defined above, and with each field encoded with the Most Significant Byte first (known as network byte order). Note that the field names, particularly for multiplexed fields, follow historical practice.
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | time_low | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | time_mid | time_hi_and_version | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |clk_seq_hi_res | clk_seq_low | node (0-1) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | node (2-5) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Admin
Ugh formatting fail. Just look up the actual RFC
https://tools.ietf.org/html/rfc4122#section-4.1
Admin
I tried to explain to them if you're not rolling over a 64bit counter, you're definitely not going to have a GUID collision. Fortran-era mechanical engineers were making a lot of the software architecture decisions at this place, and it showed...
Admin
The traditional Java date APIs (pre-Java 8) are rubbish - among many reasons, due to failure to distinguish date from date/time from date/time/timezone - but they're not so rubbish that the same parsing function will give different results in the situation described. No, that's just crap coding.
Admin
I don't think the issue is commenters "not understanding" UUIDs (which is a fairly condescending thing to say, by the way) so much as the poor soul in the article having to work with Microsoft software with inconsistent string representations for GUIDs.
Standards documents are all well and good, thank you for taking the time to show them to us, but entirely worthless once you have to work with things that do not implement them.
Admin
DVorak KEYBOARD is real wtf.
Admin
dvorak keyboard is real wtf.
Admin
Remy's comment in the article:
Or that you really, REALLY don't want to work at $STARTUP.
Admin
It's rather naive to say that there's no reason to convert a GUID to a String. You can't say that until you know what libraries you are using, what outside systems you are interfacing with, and in general what your requirements are. You might, of course, say that a library SHOULDN'T call for a GUID to be passed in as a string. But so what? That's like saying that there's no reason to have a password on your bank account because other people SHOULDN'T try to steal your money.
Now if a programmer, within one module, obtained GUIDs from two different sources, converted both to strings in two different ways, and then compared them to each other, yeah, that would be dumb.
Admin
Or I recently came across a block of code that read a GUID from the database, converted it to a string, and then, without using that string for any other purpose, converted the string back to a GUID. And thoughtfully provided a try/catch block in case the string was not a valid GUID.