<cfscript>

	// Read in the raw Binary data of the image. This is the byte
	// array that we will be hashing in the following algorithms.
	imageBinary = fileReadBinary( expandPath( "./gina_carano.jpg" ) );


	// ------------------------------------------------------ //
	// ------------------------------------------------------ //


	// Get the hash of the byte array (that IS the image) using the
	// updated ColdFusion 10 hashing function.
	imageHash = hash( imageBinary );

	// Output the image "fingerprint".
	writeOutput( "Fingerprint: " & imageHash );


	// ------------------------------------------------------ //
	// ------------------------------------------------------ //
	writeOutput( "<br />" );
	// ------------------------------------------------------ //
	// ------------------------------------------------------ //


	// I hash a byte array using the given algorithm and return a
	// 32-character Hexadecimal string. This fills in the hash()
	// function for pre-CF10 installs.
	//
	// NOTE: Does not support CFMX_COMPAT - uses MD5 by default.
	function hashBytes( bytes, algorithm = "MD5" ){

		// Get our instance of the digest algorithm that we'll use
		// to hash the byte array.
		var messageDigest = createObject( "java", "java.security.MessageDigest" )
			.getInstance( javaCast( "string", algorithm ) )
		;

		// Get the digest for the given byte array. This returns the
		// digest in byte-array format.
		var digest = messageDigest.digest( bytes );

		// Now that we have our digested byte array (as another byte
		// array), we have to convert that into a HEX string. For
		// this, we'll need a HEX buffer.
		var hexBuffer = [];

		// Each integer in the byte digest needs to be converted into
		// a HEX character (with possible leading zero).
		for (var byte in digest){

			// Get only the last 8-bits of the integer.
			var tail = bitAnd( 255, byte );

			// Get the hex-encoding of the byte.
			var hex = ucase( formatBaseN( tail, 16 ) );

			// In order to make sure that all of the HEX characters
			// are two-digits, we have to prepend a zero for any
			// value that was originall LTE to 16 - the largest value
			// that won't result in two HEX characters.
			arrayAppend(
				hexBuffer,
				(tail <= 16 ? ("0" & hex) : hex)
			);

		}

		// Return the flattened character buffer.
		return( arrayToList( hexBuffer, "" ) );

	}


	// Get the hash of the byte array using our hashBytes() function
	// which dips down into the Java layer directly.
	imageHash = hashBytes( imageBinary );

	// Output the image "fingerprint".
	writeOutput( "Fingerprint: " & imageHash );


	// ------------------------------------------------------ //
	// ------------------------------------------------------ //
	writeOutput( "<br />" );
	// ------------------------------------------------------ //
	// ------------------------------------------------------ //


	// Create an instance of our DigestUtils class - this class
	// simplifies some of the operations we just saw in the
	// MessageDigest class above, turning them into simple,
	// one-line calls.
	digestUtils = createObject(
		"java",
		"org.apache.commons.codec.digest.DigestUtils"
	);

	// Get the hash of the byte array using our hashBytes() function
	// which dips down into the Java layer directly.
	imageHash = ucase( digestUtils.md5Hex( imageBinary ) );

	// Output the image "fingerprint".
	writeOutput( "Fingerprint: " & imageHash );


</cfscript>