Secure Konami Code in JavaScript

One of the comments from the original Konami Code Project was if there was a way to protect the code so that users do not know what the code is. This is an interesting problem and inspired todays revisions to the Konami Code widget. Using a server-side one-way transformation, such as MD5, and then doing the same transformation on the client-side, allows the developer to specify a secret code. The code was also revised to use an algorithm that is faster with larger sets of char codes (ex. the user has been interacting with the page for a while and pressed many keys), by using the Array.length and Array.slice the smallest set of char codes can be compared instead of the whole list.

Example 1: KonamiCode Singleton

(function() {
		// constants
	var Y = YAHOO.util,
		YE = Y.Event,
		YL = YAHOO.lang,

		// local namespace
		_F = function() {},
		_keyPressed = [],
		_code = 38,38,40,40,37,39,37,39,66,65,13,
		_cryptoFx = function(typedCode, storedCode) {return typedCode=== storedCode;},
		_length = 11,
		_that = null,

		// event namespace
		_E = {
			onKey: function(e) {
				var keyCode = YE.getCharCode(e);

				if (_keyPressed.length >= _length && _cryptoFx(_keyPressed.slice(_keyPressed.length - _length).join(,), _code)) {
					_keyPressed = [];

	// public namespace
	YL.augmentObject(_F.prototype, {

		 * The event to fire after the Konami code is successfully entered.
		 * @event onCodeEntered
		EVENT_CODE_ENTERED: KonamiCode.CodeEntered,

		 * Change the code; use a string of comma separated key codes.
		 * @method changeCode
		 * @param code {String} Required. The key codes.
		 * @public
		changeCode: function(code) {
			if (YL.isString(code)) {
				_code = code;
				_length = code.split(,).length;

		 * Change the code and apply a cryptography method.
		 * @method useCrypto
		 * @param code {String} Required. The encrypted key codes.
		 * @param cryptoFx {Function} Required. The cryptography function, see cryptoFx above for function signature.
		 * @param length {Number} Required. The number of characters that originated the encrypted key codes.
		 * @public
		useCrypto: function(code, cryptoFx, length) {
			if (YL.isString(code) && YL.isFunction(cryptoFx) && YL.isNumber(length)) {
				_code = code;
				_cryptoFx = cryptoFx;
				_length = length;

	YL.augmentProto(_F, Y.EventProvider);
	YE.on(document, keydown, _E.onKey);

	_that = new _F();
	Core.Controller.KonamiCode = _that;

The code has also been restructured to leverage YUI EventProvider. Instead of explicitly defining a CustomEvent (onCodeEntered) on the KonamiCode object, the EventProvider augments the object with a subscribe function. Then developers just need to use a static key to reference the event:

Example 2: Subscribing to the Konami Code

Core.Controller.KonamiCode.subscribe(Core.Controller.KonamiCode.EVENT_CODE_ENTERED, function() {

Now there is two new functions on KonamiCode: changeCode and useCrypto. The changeCode method simply replaces the konami code with the comma-delimited string of char codes provided. The useCrypto method requires three parameters: the encrypted code, the JavaScript function to encrypt with, and the length of the code (this is required, because there is know way of knowing the code length from the encrypted code). The encrypted code parameter should be encrypted server-side and passed to the JavaScript. The encryption function should accept two parameters: the currently typed code and the stored code respectively. Here is a PHP example of how to implement an encrypted konami code:

Example 3: Encrypted PHP KonamiCode

Thanks for visiting. Don't forget to subscribe to the rss feed. For questions, see the about page.