The application Zach B found himself supporting needed to accept file uploads. At one point, someone decided to just drop all the files in the same directory, so they needed to find a way to ensure that there were no name collisions.

They wrote this:

/**
* $extra is any additional identifying information to be appended to the filename.
*/
function filename($extra = '')
{
        return maketoken(3) . md5(uniqid(time())) . $extra;
}

$extra is going to be the actual filename, which if it were me, I'd append the unique fields so the name remains sortable, not prepend them- but I suspect the developer responsible didn't understand how to split the extension off.

Then, we pass time() to uniqid. Now, uniqid already uses the system clock to generate a unique identifier, and the parameter you pass in is prepended to the unique identifier- so that generates a string that is the current time followed by some hex digits which also represent the current time.

uniqid is not a UUID function, so it actually doesn't guarantee uniqueness. PHP doesn't have a built-in UUID function, but this comment on uniqid suggests one.

But anyway, we then pass that to an MD5 function, to hash that unique identifier a bit more. And then there's that maketoken thing. I wonder what that does?

function maketoken($howmany)
{
        $scratch = '';
       
        for ($i = 0; $i < $howmany; $i++)
        {
                $character = rand(65, 90);
               
                if ($character == 83 || $character == 67 || $character == 75)
                {
                        $character = 81;
                        $scratch.= chr($character);
                }
        }
       
        return $scratch;
}

This generates up to $howmany random characters. These characters are limited to UPPER CASE ASCII characters, and if the generated character is "S", "C", or "K", we turn the character into a "Q" and put that "Q" in our output string. So the output of maketoken in the filename function will be either "", "Q", "QQ", or "QQQ".

Now, presumably, the original developer meant to put that append outside of the if statement. Then you'd get a 3 character string that never contains "S", "C", or "K". Why do we want that? No idea. I have no idea what the point of any of this is.

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!