8

Here's a fucking challenge:

Generate an MD5 hash in React Native!

crypto - NOPE deprecated, react native throws when you try to import it anyway

react-native-crypto - NOPE, needs to make use of a shim that recursively edits node_modules... hmmmm yeah you think thats a good thing to have?

react-native-fast-crypto - NOPE, no TypeScript types, no documentation in general, only supports sha512?! WTF

garbage fucking idiot tooling stupid dumbass stupid splat splat barf splat

Comments
  • 11
    Just don’t use md5?
  • 9
    if a "product owner" insists on MD5, ask them why. if they can't find any _technical_ reason: tell them to stick it where the sun doesn't shine, and move the topic to /dev/null
  • 5
    Do you/they know what the word deprecated means??
  • 4
    Well, MD5 shouldn't really be used as it's no longer cryptographically secure IIRC. The only reason I think you should use it is if you're depending on some external resource that requires it, like Gravatar.
  • 1
  • 2
    @KDSBest always an excellent idea to use home-baked solutions for crypto topics!

    But MD5 isn't technically crypto anymore so.... Hmm.
  • 0
    You are aware that MD5 is conpletely deprecated. Any idiot with a computer can crack the hashes.
  • 2
    Ach forgot to include the blat splat splat md5 deprecated blah blah blah note on my rant

    As always, you need to know what you're doing. We're using it to deterministically define an A / B group on the fly via the sign on the little-endian of the MD5 hash of the given user ID. We use it because it's way faster than any SHA algorithm or anything else.

    Anyway, for those interested, my rage pushed me through to finally get a solution:

    import { binaryMd5 } from 'react-native-quick-md5';

    import { Buffer } from "buffer";

    export const getGroupFromUserId = (userId: string): 'A' | 'B' => {

    const hexEncodedString = binaryMd5(userId);

    // Convert the hexEncodedHash var (hex encoded as according to react-native-quick-md5)

    // and convert it back to a buffer, then get the little endian

    return Buffer.from(hexEncodedString, 'hex').readInt32LE(0) > 0 ? 'A' : 'B';

    }
  • 3
    To everyone else...

    MD5 was designed for cryptography, but it's an hashing algorithm.

    Wether one uses it for cryptography or not is another concern....

    @fullstackclown

    This looks really... Fuckity.

    I'd assume the userId is non numeric, as otherwise a modulo would do the job perfectly?

    There are less "convoluted" methods available.

    I say convoluted because hashing for the whole purpose to extract little endian and saying A or B deterministically is pretty overkill.
  • 0
    @IntrusionCM if I tell you a user ID is a GUID, how else would you do this? Okay, look into spec of GUID, see what the first character can be, blah blah blah. Then you have to reimplement if you use for example the DB ID (a long) I think this solution is the most versatile for what it needs to do.
  • 0
    If youre using md5 in a modern application for encryption reasons, you need to go back to school because youre about 20 years late on some big hashing news
  • 2
    @fullstackclown I mean, if it's a GUID then you can literally just grab any bit from the entire GUID and it should be cryptographically random, which could group into A or B. What's faster than an MD5?... No hash. And it's still deterministic.

    If it's a number, you could just use the one's place but to group into A or B. It's less random but it will still group them up, supposedly 50/50 assuming sequential user IDs
  • 1
    @fullstackclown In general, there are tons of non cryptographic and "stupid" hashes available.

    Most cryptographic hashes, even the older ones, are performance wise still "meh".

    Look e.g. for xxhash or murmurhash3.

    That to hashes.... Back to the non hashes.

    A GUID v4 is 128 bit if I remember correctly, so if it's DotNet 4 there should be BigInt support aka 128 bit integer.

    Modulo here I come ;)
  • 0
    Lol comments here "just group them into A or B"... uh YEAH thats what we need to do. But it needs to be:

    1. Deterministic

    2. 50/50 random

    Sigh, let me explain. Okay great, you've got your GUID. The first character (or any of them really, except the dashes) can be 0-9, a-f, or A-F. That's 22 possible characters. So, you pick the first 11. Fine, so if I see 0-9 or a as the first character, that's group A, all others are B. Now, if that isn't more 'fuckity' than just hashing and getting the sign, well then I'm not a dev 🤷‍♂️

    Of course, someday our A / B groups will persist down to DB level. But for now, this is still (IMO) the best on-the-fly cross-platform, cross-language method to do it. I'm not writing some hackity BS in 3 different languages to know what group a user is in
  • 0
    @fullstackclown but why not just take one of the bits from the uuid which should already be a deterministic cryptographically strong pseudo random value? 🤔
  • 2
    @fullstackclown

    *Pancakes? You need pancakes.*

    The thing about your solution that tickles me is not the hash, rather it's performance.

    MD5 is slow.

    It's btw the same with the go to recommendation of SHA 2 - even cryptographically, there are better solutions available.

    It's sometimes terrifying how devs are stuck to a standard without asking why -
    "File" - MD5
    "Crypto" - SHA
    ...

    Etc. Many _great_ alternatives exist, some are just less known.

    E.g. Blake 3 - the rust implementation is insanely fast.

    In one of our projects, where large files (think archives with a _minimum_ of 2 GB size) that switch alone shrunk the time for hashing to 30 %...

    Yeah.

    3 hours vs 54 minutes.

    This was btw just a default run, we didn't even bother to optimize for threading or stuff.

    I get why you chose hashing - anything that cannot be represented as a 64 bit integer is tricky, especially with the additional constraint of language independent and cross platform given.

    I mentioned Murmur Hash 3 - many databases have either extensions or ship it by default. :-)

    It's e.g. useful for partioning in databases based on compound information (multiple values).

    Nuff said. Eat the pancakes 🥞

    Wasn't meant offensively.
  • 1
    @IntrusionCM yeah but this is frontend. We can't just 'take the rust implementation'.

    Whatever. At this point I don't care anymore. I'll take my pancakes. 🥞 The thing ships to production tomorrow, I don't have any further concerns...

    Although as a rude sidenote / comment: people wonder why they can't get hired / fail interviews / whatever - imagine spending more than 2 hours designing or crafting some BS to accomplish said task in the original post.

    #1 thing I'll always remember: "Software is a human enterprise. It has nothing to do with machines"

    More people need to learn that.
  • 1
    @fullstackclown you misunderstood my example. It was specific for file hashing ;)

    My recommendation still sticks with murmurhash3 / xxhash for these cases - trivial algorithms with focus on high throughput.

    Regarding the rude comment: Not rude at all. The joyful thing is here - I just proposed alternatives I came up with in less than 5 secs.

    I like devRant mostly because it's for me a lot of times like a brain jogging.

    I'm curious by nature and like to know more.

    Software, Hardware, Architecture... I don't care.

    "Software is a human enterprise"... Never heard the sentence before.

    But it doesn't make much sense to me.

    For me, software and everything else is rather an endless set of variables - a big combination puzzle that one will never crack but that has always somewhere a surprise stored.
  • 0
    Exepting checking against the few sites that distribute binaries hashed with md5 why would you not just use Sha ?
  • 0
    And why use react ?
  • 1
    @AvatarOfKaine Ah I'm sorry we didnt use your framework of choice. Let me inform the team and we'll rewrite our 20+ screen app to something else
  • 0
Add Comment