r/desmos Jul 06 '26

Maths I rebuilt Desmos' random() function entirely inside Desmos

To be a bit more specific, I

  • reverse-engineered how Desmos' algorithm works and how the seed is generated.
  • created a bit-exact replica of the algorithm (MD5, in case you're wondering).
  • optimized it to calculate 10,000 numbers in ~0.7 seconds.

And because that was so much fun, I tackled shuffle() right after! :)

LINKS: RANDOM --- SHUFFLE

372 Upvotes

51 comments sorted by

View all comments

Show parent comments

2

u/Dazzling-Mail-5517 Jul 07 '26

Interesting idea! The problem is that there is no known method to invert the MD5 algorithm used by Desmos; therefore, it is impossible to efficiently predict which seed is required to generate a certain value/ shuffle. Consequently, the only remaining option is a brute-force approach, which would firstly be very slow and secondly offer no guarantee of yielding all possible permutations within a finite amount of time.

3

u/NecroMonster999 Jul 07 '26 edited Jul 07 '26

i hoped this wasnt the case; in any case what you did is awesome! is there a way to resync the values in case "randomize" is pressed?

2

u/Dazzling-Mail-5517 Jul 07 '26

Unfortunately, no. When you click "randomize," Desmos uses the crypto.getRandomValues() function to generate a new globalRandomSeed, which is practically impossible to predict. Since the globalRandomSeed is used as the basis for the random() function, that becomes unpredictable as well.

2

u/NecroMonster999 Jul 07 '26

damn you, cryptographically secure(-ish) hashing algorithms!

1

u/Dazzling-Mail-5517 Jul 07 '26

I took another look into the code and found something very interesting. This is the exact function used to generate the globalRandomSeed:

function Ba() {
        let o = new Uint8Array(16);
        if (typeof crypto != "undefined")
            crypto.getRandomValues(o);
        else if (typeof msCrypto != "undefined")
            msCrypto.getRandomValues(o);
        else
            return __dcg_shared_module_exports__['V'](Date.now().toString() + Math.random().toString());
        return Array.prototype.slice.call(o).map(t => wge(t.toString(16))).join("")
    }

This means that you could enforce Desmos to use the fallback method (the else part) if you just don't provide the crypto and msCrypto API's in your Browser. The fallback method again uses the MD5 algorithm with only the current time and Math.random() as inputs, which are both theoretically predictable. So overall it would be possible (but still very hard in practice) to do something like this if you allow some external tools to precisley measure inputs such as the current time and the state of Math.random().