How not to create a Random string

It is surprising to see how after all the code floating around people still find it hard to create random numbers. In a recent piece of code I encountered, the following was used to generate a string of random numbers. The code was written to provide a random string to be passed to a email verifier system – the type wherein a new user when he subscribes to a website needs to verify his email by clicking on a provided link.

The verification code was created by the following lines.

$alphanum  = "123456789";

# $insertedId is the id of the last database insert
# $verification_code is saved in the database
$verification_code = (substr(str_shuffle($alphanum), 0, 5)) . $insertedId;

# Good till here, but the following line botches it up,
# the generated number is further multiplied by a constant.
$verificationCode  = $verification_code * (12345) #ouch!;

# $verificationCode is now sent through the email link as a GET parameter,
# e.g$verificationCode

When the user clicked on the verify email link the verification code was retrieved from the GET parameter, divided by a constant number and the result compared to the original verification code stored in the database.

$verificationCode = $_GET['vid'];
$verifyCode = $verificationCode / 12345;

The problem was that once in a while the random string generation code would spew a somewhat larger number, which PHP would happily convert to a exponential format and pass it over the email link in the GET parameter.

The number which when retrieved by the system would obviously not compare with the original and the system would flag the email link as invalid, robbing the site owner of potential subscribers.

Rather than go with all the rigmarole, a good way would have been to generate a random string using the following.

$verificationCode  =  md5(uniqid(rand(), true)) . time();

The point being that you cannot be too careful when dealing with numbers, a single overlooked fact can trip you.

5 thoughts to “How not to create a Random string”

  1. Nice post. I think this is where UUIDs work wonders. I have worked with a couple of sites where the verification code sent to the users email address was just their UUID in the databases. Because of the nature of UUIDs I find the the semi-random nature of their generation is enough to counteract most if not all of the brute forcing effects. Also if all your using it for is user verification (and still requiring the user to login after verification) it doesn’t matter how many accounts the potential hacker activates.

  2. To nit-pick:

    It was also a mistake to use str_shuffle, because it reduces the number of possible values.
    10*9*8*7*5 instead of 10^5 in this case.

  3. Why would you still append the time to uniqid(rand(), true)? Uniquid already contains the time (in miliseconds).

Leave a Reply

Your email address will not be published.