VHD Attach 3.50

VHD Attach screen

Here is new version of VHD Attach.

Due to popular demand, you can now change drive letter from within application. While this is not strictly VHD related task, I got it as suggestion from enough people. See, if you ask for something enough times, it is done eventually.

This version should also work on Windows 8 but do notice that there was no extensive testing. Probably new version will be out when Windows 8 is officially published.

ISO 8601 Week

For a program of mine I needed to get week number. Simple, I though, I’ll just use standard function. I knew from past that C# had one. I also knew that it offered me a choice of how to determine first week. I could start counting weeks starting from first day in year, first full week or first week that has four days in it.

Short trip to Wikipedia has shown that ISO 8601 date standard has part that deals with weeks. One of alternative definitions read that it is “the first week with the majority (four or more) of its days in the starting year”. With that sorted out, code was trivial:

private static int GetWeekNumber(DateTime date) {
    var cal = new GregorianCalendar();
    return cal.GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}

Nice, clean and wrong. Week numbers for all years that begin on Thursday were incorrect. For example, January 1 2009 is Thursday. According to ISO 8601 that means that this is first week and Monday, December 29 2008 is it’s first day. Result should have been 1 but .NET returned 53 instead. Probably something to do with United States and week starting on Sunday.

In any case, new algorithm was needed. Simplest thing would be to do all steps that a person would do in order to calculate it:

private static int GetWeekNumber(DateTime date) {
    var currNewYear = new DateTime(date.Year, 1, 1);
    var currFirstThursday = currNewYear.AddDays((14 - (int)currNewYear.DayOfWeek - 3) % 7);
    var currFirstMonday = currFirstThursday.AddDays(-3);

    if (date >= currFirstMonday) {
        var nextNewYear = new DateTime(date.Year + 1, 1, 1);
        var nextFirstThursday = nextNewYear.AddDays((14 - (int)nextNewYear.DayOfWeek - 3) % 7);
        var nextFirstMonday = nextFirstThursday.AddDays(-3);
        if (date >= nextFirstMonday) {
            return 1 + (date.Date - nextFirstMonday).Days / 7;
        } else {
            return 1 + (date.Date - currFirstMonday).Days / 7;
        }
    } else {
        var prevNewYear = new DateTime(date.Year - 1, 1, 1);
        var prevFirstThursday = prevNewYear.AddDays((14 - (int)prevNewYear.DayOfWeek - 3) % 7);
        var prevFirstMonday = prevFirstThursday.AddDays(-3);
        if (date >= prevFirstMonday) {
            return 1 + (date.Date - prevFirstMonday).Days / 7;
        } else {
            return 1 + (date.Date - currFirstMonday).Days / 7;
        }
    }
}

Can this code be written shorter? Of course:

private static int GetWeekNumber(DateTime date) {
    var day = (int)date.DayOfWeek;
    if (day == 0) { day = 7; }
    var nearestThu = date.AddDays(4 - day);
    var year = nearestThu.Year;
    var janFirst = new DateTime(year, 1, 1);
    return 1 + (nearestThu - janFirst).Days / 7;
}

This algorithm is described on Wikipedia so I will not get into it here. It is enough to say that it is gives same results as first method but in smaller volume.

Finally I could sleep at night knowing that my weeks are numbered. :)

P.S. If someone is eager to setup their own algorithm, here is test data that I have used. Most of them were taken from ISO 8601 week date Wikipedia entry but I also added a few:

Sat 01 Jan 2005  2004-W53-6
Sun 02 Jan 2005  2004-W53-7
Mon 03 Jan 2005  2005-W01-1
Mon 10 Jan 2005  2005-W02-1
Sat 31 Dec 2005  2005-W52-6
Mon 01 Jan 2007  2007-W01-1
Sun 30 Dec 2007  2007-W52-7
Tue 01 Jan 2008  2008-W01-2
Fri 26 Sep 2008  2008-W39-5
Sun 28 Dec 2008  2008-W52-7
Mon 29 Dec 2008  2009-W01-1
Tue 30 Dec 2008  2009-W01-2
Wed 31 Dec 2008  2009-W01-3
Thu 01 Jan 2009  2009-W01-4
Mon 05 Jan 2009  2009-W02-1
Thu 31 Dec 2009  2009-W53-4
Sat 02 Jan 2010  2009-W53-6
Sun 03 Jan 2010  2009-W53-7

P.P.S. Getting year and day in week is quite simple and thus left for exercise of reader. :)

Padding Length

Quite a lot of modern protocols have padding requirements. One great example is Diameter. All attribute values there are aligned on 4-byte boundary. Reason behind such complication is in data structure alignment. While only benefit on x86 architecture is (usually minor) speed increase, on RISC processor it makes difference between doing some work or crashing in flames.

Most common alignment is on 4-byte boundaries. If we have something with length of 5, aligned length will be 8. However for length of 4, aligned length is also 4. Code is as simple as it gets:

public int GetPaddedLength(int len) {
    if ((len % 4) == 0) {
        return len;
    } else {
        return len + 4 - (len % 4);
    }
}

Lengths that fall into alignment by their own devices are not touched while all other get small boost. Of course that code can be a bit shorter if one is comfortable with C# ternary operator (present in almost all C-like languages):

public int GetPaddedLength(int len) {
    return ((len % 4) == 0) ? len : len + 4 - (len % 4);
}

And, if other alignment is needed, small generalization is all it takes:

public int GetPaddedLength(int len, int align) {
    return ((len % align) == 0) ? len : len + align - (len % align);
}

Null Object Pattern

One of more dangerous patterns that I have seen is Null object pattern. Premise is simple enough: Instead of your function returning null (e.g. when it cannot find an item) it should return special empty object. This avoids null references exception if such object is accidentally used. With simple change to way how we return object we just got rid of crashes. What could go wrong?

Well, someone might implement new functionality a year down the road. Not knowing about this behavior he will check for null in some border line case. Since change is small, no one will do full testing (of course, in real world, any change triggers full retesting :)). His borderline behavior just went from well defined (check for null and take action) to pray that empty object does not get inserted into main program flow.

Exceptions are your friend. That kind of friend that will kick you in the arse when you do something wrong. Having empty object instead of null will indeed stop the crash. However, there is now empty object floating around. Programs are complex and this object is bound to get into wrong place. Best case scenario is that no data gets corrupted.

Null reference exceptions that you would get traditionally are probably among simplest exceptions that you can find in the wild. From stack trace you can see where object is null and just backtrack from there. And probability of data corruption is quite low since program crashed before actually doing anything with affected object. Even if something wrong got inside, crash is quite a clear signal that something is amiss.

Debugging any errors produced by this pattern is not a trivial task. You will probably only notice that something is wrong on data. And you will not notice that error immediately. No, it will be in database for days, weeks if not years until some TPS report exposes it to public. And then you need to find offending code. Talk about needle in haystack…

I view using this pattern as telling someone to kick you in the balls. Maybe there is good reason to take such action, maybe there are even some benefits. Nevertheless there will be some pain involved and one should better be sure that this is really action that is needed.

QText 3.20

QText screen

New version of QText has one feature that I planned for a while now.

Just right-click on any tab, select encrypt and chose your password. Upon first access to tab you will get password prompt and file will be decrypted and left open in order to be used. As soon as program is closed and taken to tray, file will be locked again. Other than password prompt, look and feel of encrypted files should be same as it was before.

For those that like three-letter abbreviations, 256-bit AES in CBC mode is name of the game. Security-wise it might not be a best choice since (in chosen implementation) it derives key and IV directly from password. Since that operation is very fast, unfortunately this also means that is very fast to mount brute-force attack. Of course, the longer password, the more resilient it will be. I wouldn’t save my nuclear-launch codes here, but everything else should be safe.

I always tried to keep data accessible to user even without QText installed. That was main reason driving decision to use text files and folder structure as storage mechanism instead of single file. Availability of user data is what also drove me to use OpenSSL encryption here. OpenSSL is available on virtually every platform. Because of same algorithm it is possible to manually decrypt each file if need arises:

openssl aes-256-cbc -d -in file.txt.aes256cbc -out file.txt -k "password"

I consider this a good trade.

As always, upgrade is available from within application or at these pages.