Skip to main content
Ben Nadel at CFUNITED 2009 (Lansdowne, VA) with: Steve Bryant
Ben Nadel at CFUNITED 2009 (Lansdowne, VA) with: Steve Bryant

RandRange() With Algorithm Argument Uses In Lucee CFML

Published in Comments (2)

Six years ago, I looked at generating "cryptographically secure" random tokens in ColdFusion by using Java's class. To which, Henry Ho pointed out that he had been using randRange() with the SHA1PRNG algorithm for the same purpose. After Henry's comment, I then played around with generating random bytes using randRange(); however, since I was on Adobe ColdFusion at the time, I had no idea what the actual implement was doing under-the-hood. Now that I'm on Lucee CFML, which is open-source and fully available on GitHub, I can see what is happening; and, according to the source code, the randRange() function-when used with a non-CFMX_COMPAT algorithm-uses the library in Lucee CFML

Here's a snippet from the Lucee CFML source code at the time of this writing:

static Random getRandom(String algorithm, Double seed) throws ExpressionException {

	algorithm = algorithm.toLowerCase();

	Random result = randoms.get(algorithm);

	if (result == null || !seed.isNaN()) {
		if (CFMXCompat.ALGORITHM_NAME.equalsIgnoreCase(algorithm)) {

			result = new Random();
		else {

			try {
				// imported reference.
				result = SecureRandom.getInstance(algorithm);
			catch (NoSuchAlgorithmException e) {
				throw new ExpressionException("random algorithm [" + algorithm + "] is not installed on the system", e.getMessage());

		if (!seed.isNaN()) result.setSeed(seed.longValue());

		randoms.put(algorithm, result);

	return result;

As you can maybe see (Java's not really my bag), when the getRandom() function is called with an algorithm other than CFMX_COMPAT, Lucee is calling:


Which means, when you invoke the ColdFusion function, randRange() and you pass in SHA1PRNG as the algorithm, you end up using an instance of the SecureRandom class, not the Random class (which is the default implementation).

Now, that's not to say that using randRange() with SHA1PRNG is the same as using the SecureRandom class itself. From what I can see in Lucee's source code, the instance of SecureRandom is cached the first time it is accessed; and then, used as-is going forward. Which means, it is only ever seeded once. One benefit of using the SecureRandom class directly is that you can occasionally call re-seed the secure random generator to try and break-up any pattern recognition in the output.

That said, I am not a security expert by any stretch of the imagination. As such, I don't really know how important it is to reseed the generator; especially if there's no place within your application where a malicious actor can see many sequential results of the random number output.

To make this randRange() fact a little more funzies, let's take a look at using the SHA1PRNG algorithm to generate secure, random passwords in ColdFusion. I actually wrote about random password generation in ColdFusion back in 2007 (oh my!); so, I'm gonna take that old concept and revamp it for modern Lucee CFML development.

First, I'm going to take my random password generation logic and wrap it up in a ColdFusion component so that we can reuse it. Our component is going to define set of characters such as "upper case" and "lower case" characters. We're then going to use the randRange() function to randomly select characters out of those sets.

Note that I'm extracting characters by treating strings as arrays of characters, a lovely little delighter within Lucee CFML:

	output = false
	hint = "I generate random passwords using the cryptographically secure SHA1PRNG algorithm."

	* I initialize the password generator.
	public void function init() {

		// NOTE: I'm not using "special characters" in this demo for simplicity. Plus,
		// length is really the limiting factor when it comes to password security.
		variables.lowerCaseValues = "abcdefghijklmnopqrstuvwxyz";
		variables.upperCaseValues = lowerCaseValues.ucase();
		variables.numberValues = "0123456789";
		variables.allValues = ( lowerCaseValues & upperCaseValues & numberValues );


	// ---
	// ---

	* I generate a secure, random password of the given minimum length.
	public string function generatePassword( numeric minLength = 15 ) {

		// Ensure that we have at least one upper, one lower, and one numeric character
		// in our password. We can then use the composite set of all characters to
		// fulfill the minimum length requirement.
		var characters = [
			randomChar( lowerCaseValues ),
			randomChar( upperCaseValues ),
			randomChar( numberValues )

		while ( characters.len() < minLength ) {

			characters.append( randomChar( allValues ) );


		return( characters.toList( "" ) );


	// ---
	// ---

	* I select a random character from the given string using the SHA1PRNG algorithm for
	* cryptographically strong randomness.
	private string function randomChar( required string value ) {

		var index = randRange( 1, value.len(), "SHA1PRNG" );

		// NOTE: In Lucee CFML, you can treat a String like an Array of characters!
		return( value[ index ] );



As you can see, our generatePassword() method starts out by selection one upper case, one lower case, and one numeric character. This is try and comply with some common "password complexity" rules. It then fleshes-out the rest of the characters using the composite set of all inputs.

Note that the selection of random characters is using the SHA1PRNG algorithm.

Now, to test this, we just instantiate it and call it a bunch of times:


	passwordGenerator = new PasswordGenerator();

	loop times = 20 {

		echo( passwordGenerator.generatePassword( 20 ) & "<br />" );



And, when we run this ColdFusion code, we get the following randomly generated passwords:


There you go - we're using the randRange() ColdFusion function with the SHA1PRNG algorithm in order to leverage the class for cryptographically secure random number generation which, in turn, allows us to generate secure random passwords.

Want to use code from this post? Check out the license.

Reader Comments


Very nice, Ben.

This would work well, as a routine to offer to users, on a sign up page.

Of course, if you are using an iPhone, it offers this service within iOS, when the password field gains focus.
But, for desktop users, you could add a link like "Generate Password" and voila it could hit an Ajax request that hits your CF routine.

Great stuff! 😀



I had no idea the iOS offers the option to generate passwords. Very cool! That said, I tend to create all my passwords in 1Password first, and then just copy/paste them into the form. I don't even know what 99% of my passwords are these days 😜

Post A Comment — I'd Love To Hear From You!

Post a Comment

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel