New DAAP Release!

Now that Windows 10 has launched, I felt that it was time to update the awful Windows 8 DAAP application. The Windows 8 version was a fast port of the much better phone version, but with worse UI. For the Windows 10 version, I decided to put a little bit more effort to emulate the Groove music application that ships as part of the OS. Here are some stills from the new Windows 10 version. Let me know what you think in the comments below.

The initial setup wizard

Albums

All songs

Search results

New features include:
  • Search support
  • Change server support
  • Windows 10 support
  • Refreshed look and feel

Web Optimization {version} pattern in bundles

While creating a website using Web Optimization to handle bundling, I became curious as to what the {version} pattern matched. I couldn't find documentation for this besides what it outlined here:

The bundling framework follows several common conventions such as:
•Selecting “.min” file for release when “FileX.min.js” and “FileX.js” exist. 
•Selecting the non “.min” version for debug.
•Ignoring “-vsdoc” files (such as jquery-1.7.1-vsdoc.js), which are used only by IntelliSense. 

Digging into the source code here, I was able to find exactly what {version} matches, the C# regex @"(\d+(\s*\.\s*\d+){1,3})(-[a-z][0-9a-z-]*)?". This means it matches:
1 or more digits followed by
   0 or more whitespace followed by
   the '.' character followed by
   0 or more whitespace followed by
   1 or more digits followed by
the preceding group at least 1 times but no more than 3 times optionally followed  by
   the '-' character followed by
   any a-z character followed by
   0 or more a-z characters or numbers
Example matches would be:
  • 1.23.23-a9
  • 1.23.23
  • 2.34
  • 2.2-min
  • 2
I hope that helps clears things up for some people.

Base32 Decoding in JavaScript

When working on the Google Authenticator web page, I realized that I needed to base32 decode the secret given from Google to get to the raw bytes. For those unaware, Base32 encoding is a mechanism to represent arbitrary binary data (1s and 0s) into an alphanumeric representation that is more convenient for transport (typing, etc.). Base32 encoding is exactly like hexadecimal or octal, where binary data is represented using different characters (0-9, A-F in hex, 0-7 in octal) except Base32 encoding uses even more alphanumeric characters (2-7, A-Z) to reduce the space required to represent the same number of bits. Looking around I couldn't find a well tested implementation of this, so I decided to write my own. I used this opportunity to explore unit testing a JavaScript method using QUnit. Let's start with gathering the test cases. The RFC has some test vectors, so obviously those will be included:
test("Test Vectors", function () {
    // Base32Decode should correctly decode the test vectors from the RFC
    strictEqual(Base32Decode("").length, 0, "Base32Decode should return an empty array for the empty string");
    ok(compareUint8ArrayToString(Base32Decode("MY======"), "f"), "Base32Decode should return 'f' for 'MY======'");
    ok(compareUint8ArrayToString(Base32Decode("MZXQ===="), "fo"), "Base32Decode should return 'f' for 'MZXQ===='");
    ok(compareUint8ArrayToString(Base32Decode("MZXW6YQ="), "foob"), "Base32Decode should return 'foob' for 'MZXW6YQ='");
    ok(compareUint8ArrayToString(Base32Decode("MZXW6YTB"), "fooba"), "Base32Decode should return 'fooba' for 'MZXW6YTB'");
    ok(compareUint8ArrayToString(Base32Decode("MZXW6YTBOI======"), "foobar"), "Base32Decode should return 'foobar' for 'MZXW6YTBOI======'");
});

Obviously these tests won't pass until we have a working Base32 decoder. The decoder is fairly straight-forward for inputs that don't have padding (i.e., the number of bytes are multiples of 40). In that case, you simple map the bits per the RFC:

|__A__|__B__|__C__|__D__|__E__|__F__|__G__|__H__|__I__|__J__|__K__|__L__|__M__|__N__|__O__|__P__|__Q__|__R__|__S__|__T__|__U__|__V__|__W__|__X__|__Y__|__Z__|__2__|__3__|__4__|__5__|__6__|__7__|
|00000|00001|00010|00011|00100|00101|00110|00111|01000|01001|01010|01011|01100|01101|01110|01111|10000|10001|10010|10011|10100|10101|10110|10111|11000|11001|11010|11011|11100|11101|11110|11111

The RFC goes into detail about what cases are possible with padding, etc. but I'll leave that as an exercise to the reader. I could have made the code smaller, but I wanted to be clear and follow the RFC as closely as possible. Here is the implementation:

var Base32Decode = function (base32EncodedString) {
    /// Decodes a base32 encoded string into a Uin8Array, note padding is not supported
    /// The base32 encoded string to be decoded
    /// The Unit8Array representation of the data that was encoded in base32EncodedString
    if (!base32EncodedString && base32EncodedString !== "") {
        throw "base32EncodedString cannot be null or undefined";
    }

    if (base32EncodedString.length * 5 % 8 !== 0) {
        throw "base32EncodedString is not of the proper length. Please verify padding.";
    }

    base32EncodedString = base32EncodedString.toLowerCase();
    var alphabet = "abcdefghijklmnopqrstuvwxyz234567";
    var returnArray = new Array(base32EncodedString.length * 5 / 8);

    var currentByte = 0;
    var bitsRemaining = 8;
    var mask = 0;
    var arrayIndex = 0;

    for (var count = 0; count < base32EncodedString.length; count++) {
        var currentIndexValue = alphabet.indexOf(base32EncodedString[count]);
        if (-1 === currentIndexValue) {
            if ("=" === base32EncodedString[count]) {
                var paddingCount = 0;
                for (count = count; count < base32EncodedString.length; count++) {
                    if ("=" !== base32EncodedString[count]) {
                        throw "Invalid '=' in encoded string";
                    } else {
                        paddingCount++;
                    }
                }

                switch (paddingCount) {
                    case 6:
                        returnArray = returnArray.slice(0, returnArray.length - 4);
                        break;
                    case 4:
                        returnArray = returnArray.slice(0, returnArray.length - 3);
                        break;
                    case 3:
                        returnArray = returnArray.slice(0, returnArray.length - 2);
                        break;
                    case 1:
                        returnArray = returnArray.slice(0, returnArray.length - 1);
                        break;
                    default:
                        throw "Incorrect padding";
                }
            } else {
                throw "base32EncodedString contains invalid characters or invalid padding.";
            }
        } else {
            if (bitsRemaining > 5) {
                mask = currentIndexValue << (bitsRemaining - 5);
                currentByte = currentByte | mask;
                bitsRemaining -= 5;
            } else {
                mask = currentIndexValue >> (5 - bitsRemaining);
                currentByte = currentByte | mask;
                returnArray[arrayIndex++] = currentByte;
                currentByte = currentIndexValue << (3 + bitsRemaining);
                bitsRemaining += 3;
            }
        }
    }

    return new Uint8Array(returnArray);
};

I've added more tests around padding and other specifics you can find at the source below, but enjoy a live demo converting base32 encoded strings to hexadecimal:

You can find the source for both the tests and the actual decode on github here: Base32Decode in JavaScript.
Also, if you'd like, you can run the tests directly from your browser via this link.

Google Authenticator in HTML5 with WebCrypto

I was poking around the web cryptography API and noticed how powerful it was. It even includes the ability to perform HMAC-SHA1 via the sign method. That is all you need to create TOTP one time passwords. I've done some work in the past on TOTP and knew that it is the backing algorithm for Google's two factor authentication.

Here is the main method that generates the token given the secret, which is base32 encoded. I wrote this in Microsoft's TypeScript, since I think it is great and definitely eased development. For those unfamiliar with Typescript, it is a superset of normal JavaScript so it should be pretty easy to read regardless.
function GenerateToken(base32EncodedSecret: string, callback: (number) => void): void {
    if (!msCrypto) {
        throw "MsCrypto not found";
    }

    // Google by default puts spaces in the secret, so strip them out.
    base32EncodedSecret = base32EncodedSecret.replace(/\s/g, "");

    // This method decodes the secret to bytes, the code is excluded here.
    var keyData: Uint8Array = GoogleAuthenticator.Base32Decode(base32EncodedSecret);
    var time: number = Math.floor(Date.now() / 30000);
    var data: Uint8Array = GoogleAuthenticator.NumericToUint8Array(time);

    // We need to create a key that the subtle object can actualy do work with
    var importKeyOp: KeyOperation = msCrypto.subtle.importKey("raw", keyData, { name: "HMAC", hash: "SHA-1" }, false, ["sign"]);

    importKeyOp.onerror = function (e) {
        console.log("error event handler fired.");
        callback(-1);
    }

    importKeyOp.oncomplete = function (e) {
        var key: Key = e.target.result;
        // HMAC the secret with the time
        var signkey = msCrypto.subtle.sign({ name: "HMAC", hash: "SHA-1" }, key, data);

        signkey.onerror = function (evt) {
            console.error("onerror event handler fired.");
            callback(-1);
        };

        signkey.oncomplete = function (evt) {
            // Now that we have the hash, we need to perform the HOTP specific byte selection
            // (called dynamic truncation in the RFC)
            var signature: ArrayBuffer = evt.target.result;

            if (signature) {
                var signatureArray: Uint8Array = new Uint8Array(signature);
                var offset: number = signatureArray[signatureArray.length - 1] & 0xf;
                var binary: number = ((signatureArray[offset] & 0x7f) << 24) |
                    ((signatureArray[offset + 1] & 0xff) << 16) |
                    ((signatureArray[offset + 2] & 0xff) << 8) |
                    (signatureArray[offset + 3] & 0xff);
                callback(binary % 1000000);

            } else {
                console.error("Sign with HMAC - SHA-1: FAIL");
                callback(-1);
            }
        };
    };
}

Setup Process


Token


For those of you who are worried about how this changes the multi-factor part of multi-factor auth, you should worry not. The demo page below saves the secret in the localStorage, which is device specific. So having the secret is an indicator that you have the device. This satisfies the "something you have" factor of multi-factor authentication. Currently only Internet Explorer 11 supports some form of the msCrypto object so if you want to check out the demo, you'll need to download that.

Demo page

Where is it 5 o'clock?

In 2003 Alan Jackson and Jimmy Buffett released the song It's Five O'clock Somewhere. It went on to spend 8 weeks at number one on the Billboard Hot Country Songs. It also reached number 17 on the US Hot 100, making it a huge crossover hit.

This poses the question, where is it 5 o'clock exactly at this moment and what is going on in that area? My brother created a website http://wheresitfiveoclock.com based off of publically available material to determine where in the world it is 5 o'clock by using time zones and day light savings calculations. Sources include:
  1. http://en.wikipedia.org/wiki
  2. http://www.timeanddate.com/
  3. http://www.worldweatheronline.com/
  4. http://www.yelp.com/
I decided to create a windows phone application based off of the website http://wheresitfiveoclock.com/. This app shows you where it is currently 5 o'clock with the weather information. Hopefully, this app leads you to travel more and see more of the world. Leisure is important to your health so say it with us: It's 5 o'clock somewhere.
Main view

Live tile support

DAAP Media Player for Windows 8

DAAP, the digital audio access protocol that is commonly used by NAS devices to deliver personal music shares to your devices, is now available in Windows 8 Store! Now you can stream your music while using all of your Windows applications. The current release is available in German, English, Spanish, French, Italian, Japanese, Korean, Portuguese, Russian, and Simplified and Traditional Chinese.
Please leave any concerns or issues in the comments below.
Initial setup process.
List of albums.
Playing a song.

Coalescable Timers in Typescript

Not too many people may be familiar with the concept of coalescable timers, but they an be very useful for a power conscious application without hard real time requirements. Coalesce literally means "to grow together". In the case of timers, this means that multiple timers are allowed to be combined into one. This is usually done to reduce the number of times a computer is woken from a low power state to perform some action. This can be incredibly useful with mobile processors where power is very critical. As more and more applications move towards web applications to reduce re-implementing code in multiple mobile SDKs, it becomes necessary to introduce an implementation of coalescable timers into JavaScript, the client side logic language of modern web applications.

The idea is that when creating a timer, a tolerance value is specified that states how much variability is allowed in the timer. The tolerance allows timers with similar values to "grow together" into one timer. Examine the following example:

Timer 1: Trigger every 1 minutes with tolerance of 10 seconds
Timer 2: Trigger every 50 seconds with tolerance of 10 seconds

Coalesced Timer: Trigger every 60 seconds

Now becomes time to describe an algorithm for implementing coalescable timers. The goal is to minimize the number of times a timer is triggered. When a new timer is created, examine the existing timers, if any of the existing coalesced timers satisfy the requirements, add the new timer to the existing ones. If no existing coalesced timer handles the requirements specified, then create a new coalesced timer. Below is an implementation in TypeScript, which compiles down to basic JavaScript:

// Module containing all logic for coalescable timers
module Coalescable {
    // Variable holding all coalesced timers that are aggregating the individual timers
    var timers: CoalescedTimer[] = new CoalescedTimer[];

    export function SetCoalescableTimeout(expression: any, msec: number, tolerance: number): void {
        // Search existing coalesced timers for timers that can accomodate this request
        for (var index: number = 0; index < timers.length; index++) {
            var coalescedTimer: CoalescedTimer = timers[index];
            if (msec - tolerance < coalescedTimer.msec &&
                msec + tolerance > coalescedTimer.msec) {
                coalescedTimer.Timers.push(expression);
                return;
            }
        }

        // Create a new coalesced timer since none can accomodate this request
        var coalescedTimer: CoalescedTimer = new CoalescedTimer(msec)
        coalescedTimer.Timers.push(expression);
        timers.push(coalescedTimer);
    }

    class CoalescedTimer {
        constructor(public msec: number) {
            setInterval(function () => {
                for (var index: number = 0; index < this.Timers.length; index++) {
                    new Function(this.Timers[index])();
                }
            }, msec);
        }

        public Timers: any[] = new any[];
    }
}

Coalescable.SetCoalescableTimeout("alert('1')", 5000, 10); // Will create a new coalesced timer since none exist.
Coalescable.SetCoalescableTimeout("alert('2')", 6000, 2000); // Will be coalesced into the existing timer to run every 5000ms.


Obviously this is a first implementation. Many improvements could be made, such as minimizing distance from threshold when more than one coalesced timer exists to service a new timer request. There are also a few other interesting scenarios. Say creating a new timer means that a new coalesced timer will be created. In this case, it may make sense to move an existing timer to this new coalesced timer to reduce the difference from the requested interval and the coalesced interval. Also, cancelling or clearing a timeout should be supported.