Canned Nerd

Now with extra sparkles.

July 27, 2011
by vollerthun
0 comments

Stupid experiments

We all love accepting a stupid challenge, when it is just stupid enough, don’t we? I know I do. And a few weeks ago I read about a training plan that’ll make you run a marathon in under <INSERT HOURS>.

But the best thing is: you can reach that goal in only twelve weeks!

“That’s three months”, I thought. And then: “No way!”
But saying “no way” isn’t actually worth anything, if you haven’t at least tried it, is it? But probably that plan is intended for people who have actually been running or at least jogging before? I mean between the running you have to do in school and now? Perhaps one year is more realistic :)

So I decided to make it an experiment: can an untrained person like me (no sports at all for 15 years – yoga for the last two years, no voluntary running. Ever!)  run a marathon after a year’s training?

I don’t want to ruin my bones or change my whole life just for an experiment, so I will take it easy. These are my rules:

  • As soon as I feel uncomfortable, I declare the experiment finished and say it is impossible.
  • I will not change my lifestyle: I keep smoking my 4 to 6 cigarettes a day and won’t start a sportmen’s diet. (And I will not start eating raw meat or something. Just sayin’.)
  • I will not buy expensive gear – a cheap pair of running shoes, but no more than that.
  • I will partake in next year’s Hamburg Marathon with the goal of reaching the finish line before the broom wagon.

Being a geek, the obvious first step was: downloading an app for my android phone :P

First I tried runkeeper, but I couldn’t find an easy way to get a training plan without paying for it, so I settled with miCoach  - their website is terrible, but the app is okay and they have free training plans for, well, almost anything.

To get into that whole “running” thing, I decided to start with the “5.000m” plan. That was on June 2011, 3rd.
My first run was twenty minutes for 2 kilometres.
And just yesterday (i.e. no two months later) I finished my first 5 km run in under 30 minutes! WTF?!

It seems as if training actually works :D

I would absolutely love to get any hints about your experiences and stupid experiments. Would you like to join my experiment? Just leave a note in the comments.
I will keep you informed about my proceedings toward next year’s marathon!

cu, tom

[Update]
The original plan (the one I don’t actually use) was this one: Marathonplan für unter 4:00 Stunden zu laufen!
The one I currently follow is a 5000m interval running plan customized from miCoach by me answering some questions (how often per week; target time etc). Based on that, a training plan was created, the first training being a fitness test: “on a scale from 1 to 10, run a 4″ etc.

Based on that I then was assigned my “training zones”: blue (slow), green (aerobic), yellow (anaerobic) and red (sprint), each with my personalized speed interval.

A typical training could be: 5 mins blue zone followed by 15 mins green, 15 mins yellow and 5 mins blue.
Another training is: 10 mins blue zone, then 6 times alternating 15 second sprints (red zone) and 3 mins blue relaxation. Finish again with 10 mins blue.

That’s quite neat, although the downside is obviously that it is based on how I felt at the fitness test, not any hard values (heartbeat or so). But that’s good enough for me atm.
[/Update]

July 7, 2011
by vollerthun
0 comments

Bookmarklets for GWT-Development mode

So my new project (Just Connect by JustSoftware) uses GWT as frontend technology, which means that after struggling to set eclipse’s GWT plugin up properly, I struggled to set the Development Mode up properly :) Now that everything’s up and running, I find my self putting those pescy ?gwt.codesvr=127.0.1.1:9997 Strings into the URL to trigger the development mode (or removing the strings afterwards.

So I came up with the tiny little bookmarklets, that make my life just that tiny little bit easier:

  1. javascript:location = (location.toString().replace ('#!', '?gwt.codesvr=127.0.1.1:9997#!'));
  2. javascript:location = (location.toString().replace ('?gwt.codesvr=127.0.1.1:9997#!', '#!'));

The first one adds the pescy string to the url in the correct place, the second one removes it again.

If you want to have it, too, you can just drag these and drop them to your bookmarks: [+] [-]

Have fun.

June 15, 2011
by vollerthun
0 comments

How to use salted secure hashes as passwords

So the information that storing plaintext passwords is not such a good idea has put you into search mode? Even the quickest of all searches will bring you p.e. to the OWASP-page, which tells you that you should use some good hashing (no, MD5 is not considered good anymore). Even better if it’s salted. Even better if it’s multiply hashed. The page even has a complete example, which makes it much more useful than most other pages, I’ve seen regarding this subject. Sure, there are more pages with examples, but they all share a common problem with the OWASP-Page: their examples try to avoid all dependencies. So instead of using great existing libraries, they stubbornly implement almost everything in there. They use Arrays. And sometimes they even implement the concatenation of two byte-arrays. If you’ve ever wondered if you are the first one to stumble upon this, you’re not. Of course, you do not have to implement Array-copying these days anymore: apache commons to the rescue!

You always store the salt together with the password’s hash in the database. Together, they are checked (in the business layer!) for correctness against the password that’s used to login.
Here’s a full-working example, that uses passwords as suggested by modern security people. Just put it into a LoginExample.java file and there you go.


import java.util.HashMap;
import java.util.Map;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;

/**
 * Contains the login information as it's stored in the database
 */
class LoginDBO {

    private final String      _username;
    private final HashAndSalt _hashSalt;

    LoginDBO(String username, HashAndSalt hashSalt) {
        _username = username;
        _hashSalt = hashSalt;
    }

    public String getUsername() {
        return _username;
    }

    public HashAndSalt getHashSalt() {
        return _hashSalt;
    }

}

/**
 * Hold both hash and salt together.
 */
class HashAndSalt {

    private final String _hash;
    private final String _salt;

    HashAndSalt(String hash, String salt) {
        _hash = hash;
        _salt = salt;
    }

    public String getHash() {
        return _hash;
    }

    public String getSalt() {
        return _salt;
    }
}

/**
 * Simple full working example of business-layer implementation with fake-database.
 */
public class LoginExample {

    /** Hold user-information */
    private final Map _fakeDatabase;

    public LoginExample(Map fakeDatabase) {
        _fakeDatabase = fakeDatabase;
    }

    /** Check whether or not the given username/password-combination is valid*/
    public boolean login( String username, String password) {
        final LoginDBO loginDBO = _fakeDatabase.get(username);
        if (loginDBO == null) {
            return false;
        }

        final String hash = digest(password + loginDBO.getHashSalt().getSalt());

        if (StringUtils.equals(hash, loginDBO.getHashSalt().getHash())) {
            return true;
        }

        return false;
    }

    private static HashAndSalt createPassword(String password) {
        /*THANKS APACHE COMMONS: */
        final String salt = RandomStringUtils.randomAscii(10);
        final String hash = digest(password + salt);
        return new HashAndSalt(hash, salt);
    }

    private static String digest(String input) {
        String output = input;
        for (int i = 0; i < 10; i++ ) {
            /*THANKS APACHE COMMONS: */
            output = DigestUtils.sha256Hex(output);
        }
        return output;
    }

    private static void addUser(final Map fakeDatabase, LoginDBO loginDBO) {
        fakeDatabase.put(loginDBO.getUsername(), loginDBO);
    }

    public static void main(String[] args) {
        final Map fakeDatabase = new HashMap();
        addUser(fakeDatabase, new LoginDBO("testUser1", createPassword("simplePassword")));
        addUser(fakeDatabase, new LoginDBO("testUser2", createPassword("whatever")));
        addUser(fakeDatabase, new LoginDBO("testUser3", createPassword("hey ho")));
        addUser(fakeDatabase, new LoginDBO("testUser4", createPassword("123")));

        final LoginExample example = new LoginExample(fakeDatabase);
        System.out.println("These two logins should work:");
        System.out.println("Existing user /w correct password: " + example.login("testUser1", "simplePassword"));
        System.out.println("Other existing user /w correct password: " + example.login("testUser3", "hey ho"));

        System.out.println("These two logins should fail:");
        System.out.println("Existing user /w wrong password: " + example.login("testUser1", "simplePasswordWithTypo"));
        System.out.println("Inexistent user: " + example.login("inexistantUser", "doesntMatter"));
    }
}

That’s all folks.

June 13, 2011
by vollerthun
0 comments

balsamiq for wireframes

Whenever you find yourself drawing the same wireframes over and over again, just to add another dialog to a workflow of to change the state in a sidebar’s badge, you should definitely give balsamiq a try. This small tool specializes in creating wireframes, and that’s where it is extremely good at.

The most often used screen elements are available via a top-toolbar  so you can simply create your screens by dragging them to the place you want. You can change displayed texts, sizes and colors and all the simple stuff you’d expect from a tool like this. But it’s real strength comes to play if you have more than just one screen.

  • Modules: Say you need to display a badge in several places, just the texts are a bit different. Normally you’d go and copy and paste that badge over and over again. And then, after the next discussion, you’d go to all the places and change them piece by piece.
    With balsamiq, you can simply make the badge a module and re-use it in different places. This way you can have several instances of that same badge. Changes can be incorporated on module or on instance level, so you can easily change the displayed text in one place and keep the general text in others. Or, if you want, you can change the module and have the adjusted text in all instances.
  • Linking: Customers never read the pages upon pages of concept papers you write, do they? So in my last project, we decided to not write a concept in the first place. We started by creating wireframes, which we presented to the customers and discussed them in great detail. This way, we came to an intimate understanding of their processes and could adjust the wireframes accordingly.
    To go through the workflows, we used balsamiq’s linking feature which allows you to reference  other pages at almost all screen elements, like a link or a button. In presentation mode, you’d simply click on a link and have the current wireframe replaced with the referenced one. That’s a great way to walk your customers through the wires in a way that represents a.) their expected workflow and b.) the application as it should become.
    Of course, in the end we did write that concept anyway, but it was the first time I’d write it when I already knew all those details that break your neck when you’re halfway through the project before you discover them.
    And yes, sure enough we dropped many of the intermediate wireframes, because once we settled on a workflow, they’re not so necessary anymore. But removing wireframes is simple, because creating them is simple:
  • Cloning: To reflect a workflow closely, you want to have many wireframes with just a small bit changed: there’s an overlay or some previously hidden text is visible. Consequently you just copy that original wireframe and adjust it in these tiny places. It is but a small thing, but the ability to simply click “Clone current wireframe” is a great example of how balsamiq pays attention to the small things that make you life a tad easier: you just get your current wireframe as a new, unsaved wireframe-document. Nice.

Like every other tool, balsamiq doesn’t solve all those problems without creating a few of it’s own…

  • Cruft: Because cloning is so easy, you want to remove some of the leftovers from time to time, so they won’t be given to the customer when you export all the wireframes as a PDF (yes, it can do that).
  • XML: On the one side, it’s nice to have a text based file format, but on the other side, it makes merging harder, when you cooperatively edit the wireframes and create conflicts. Especially since the modules are by default all in one file: if you change the header and you colleague changes a badges, you sure enough have some ugly conflicts to handle. (Yes, you can have multiple module-files, so the chance of a concurrent line change is less, but it is fugly and a bit incosistent for new modules).
  • Adobe Air: Argh, wtf? How could this happen? I know that you always choose the correct tool purely on it’s technical benefits, but please, Adobe Air? Of course, it’s available for Linux as well as for Mac and Windows and even with Gentoo you’d have no problem getting it to run, but still. Do these guys have no modesty? Ah well, so maybe I do have prejudices :)
    The only real bug I’ve encountered in this regard was a strange focus-flickering issue with xmonad: every tenth second or so, the focus would switch between two windows – yes, the keyboard focus, too. I could fix it, though:
    ?import XMonad.Actions.UpdatePointer
    main = xmonad {
    logHook = updatePointer (Relative 0.5 0.5)
    }
  • Not Free: Not a problem for me: if people choose to take money for their software, I’ll either pay for it, if it’s worth it, or I won’t use it. Sure enough, balsamiq is worth it’s money, but I’m not everybody and I know people who prefer to keep their cleanroom Gobuntu without blobs. If you’re just afraid of paying at all: don’t! You’ll pay no more than a mere 80 bucks per seat after having tested the application for seven days without any restriction. And that includes free updates till the end of time. If these seven days aren’t enough for you, it’s just the removal of a subdirectory in $HOME/.appdata to reset the time (I guess on windows it’d be some registry thing), so it’s obvious: these guys are not the bad ones. Support them if you like the software!

One of the most valuable hints for making wireframes is generally to use the fattest pen you can find, because you don’t do designs right now. balsamiq sticks to this rule as all lines have a handdrawn style (all wobbly and not straight at all) and texts are generally bold. And finally, this is the first use of Comic Sans I’ve seen  that’s completely correct: since no one in their right mind would ever, ever use this font on a professional website, application, poster or magazine, the use of it in balsamiq makes abundantly clear that this is not design. Nice pun.