As some other people have pointed out, it depends on what
you intend to do with your random number. More
specifically, what is your random number going to protect?
Let me give you a spectrum of examples. Suppose you are
building a shopping cart website, and you need to assign a
number to each customer who visits. Here are some
possibilities (I will discuss the ramifications below):
- Since/If you are using a database (or some other
target for DBI), you could just allow an autoincrementing
ID to provide your CustomerID.
- You could use a self-built "random" number (like a
combination of time + IP address (like Netscape
- You could use some variant of the customer's name or
other information for the unique identifier.
- You could use a pseudo-random number, like Perl's
- You could use a "real" random number generator, like
Math::TrulyRandom or /dev/random on most UNIX
The problem with most of these solutions (in descending order
of "wrongness") is that they are easy for a
cracker/malicious individual to find, guess or generate.
- An incrementing ID is obviously easy to figure out.
Make an account, look at your ID, and try the ID below
- Self-built "random" numbers are also pretty easy to
figure out. Knowing what time it is, and watching where
someone is coming from will give the black hat a very
small number of possibilities to try.
- Letting the customer pick the key (either voluntarily,
or generated from other information) may be easy to guess,
especially when the malcontent can simply look at how you
generated his key.
- Pseudo-random numbers are much harder to figure out,
but the very definition of pseudo-random numbers means
that, given a few numbers generated from the same source,
you can (relatively) easily know ALL of the numbers which
- "Real" random number generators (like
Math::TrulyRandom, /dev/random, etc.) get their
numbers from a non-deterministic source (like interrupt
timing discrepancies). This (theoretically) does not
cause any predictability in the output.
Now, the second part of the equation is: "What data are you
trying to protect?"
If you are just going to display a random picture (like the
"Monk icons" at the upper right of your screen), security is
not your concern. Therefore, make the most efficient use of
your time and use rand(). If a cracker guesses that the
next icon to appear will be vroom's, who cares?
If, however, you will be storing a customer's personal
information (especially credit-card numbers) and allowing
the user to view that information later...You would be
shamefully negligent to use anything less
than 128-bit or greater SSL, a truly random number for the
CustomerID, strong, cryptographic-quality passwords... (and
perhaps even that is not enough).
Here is an example from one of my projects. We are building
an e-commerce site which will allow users to order products,
entering credit card information for payment. Users may
upload graphics to use in the printed product. We have
chosen not to allow the user to retrieve credit card data.
They may view and edit their uploaded logos.
For SessionIDs and CustomerIDs, we use truly random numbers.
Because we do not store intensely sensitive data, we do not
need to enforce strict, cryptographic-quality passwords. A
Customer's work is important, so we use "real" random
numbers to protect the Session. Images (uploaded logos) use
auto-incrementing IDs, since they will be hidden behind the
CustomerID (and/or SessionID). Customer's logos
are their property, so we protect them with the
random Customer key, but because logos are (presumably)
already publicly available, we do not need the highest level
of security for them. When ordering, we transmit
credit-card information over SSL and protect the card info
appropriately (e.g. NEVER send it via e-mail!), and do not
allow a user to see that information again (so we do not
have to inflict a random password and other sufficiently
paranoid measures upon the hapless visitor). Order
confirmation, which uses no sensitive data at all, happens
with security-free (what other kind is there?) e-mail.
Security is an ever-present concern in e-commerce. The
heart of data security is cryptography. The heart of
cryptography is random number generation. The weaker the
random numbers, the weaker the cryptography; therefore, the
weaker the security. Random numbers having
anything to do with security must be the
highest-possible quality. Your advice to avoid rand() in
CGI is a direct reflection of this security mindset. If you
need a random number to keep people out of places where they
do not belong, you need the best random number you can get.
rand() is not it.
Are you posting in the right place? Check out Where do I post X? to know for sure.
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
Want more info? How to link or
or How to display code and escape characters
are good places to start.