はてなのIDに使用可能な文字は?

キーワード「はてなID」によると

大文字あるいは小文字のアルファベット・0-9の数字・「-」・「_」(いずれも半角)のいずれかを3-15文字並べたもの(ただし最初の文字はアルファベットであること)から成る。アルファベットの大文字と小文字は互いに区別される。

なるほど。しかしキーワードは公式のアナウンスじゃないし、100%信用できるわけでもないよね。
はてなユーザー登録 - はてなによると

アルファベットで始まり、アルファベットか数字で終わる3文字以上、15文字以内の半角英数字

と、何とも曖昧な。アルファベット、数字以外に_とか-とか入っているよ。じゃあURLとして使用可能な文字は全部使えたりするのか・・・?とか考えていくと結構難しい。
上のユーザー登録のページで「ユーザー名をチェックする」という機能があって、そのロジックはどうなっているかというと

    check: function(){
        var username = this.inputElement.value;
        if ( username == '' ) {
            this.errMsg('ユーザー名を入力してください。')
        }
        else if ( username.length < 3 ) {
            this.errMsg('ユーザー名は3文字以上にしてください。')
        }
        else if ( 15 < username.length ) {
            this.errMsg('ユーザー名は15文字以下にしてください。')
        }
        else if ( username.match(/^hatena/i) ) {
            this.errMsg('hatenaは予約されています。')
        }
        else if ( !username.match(/^[a-zA-Z][0-9a-zA-Z_\-]{2,14}$/) ) {
            this.errMsg('使用出来ない文字が含まれています。');
        }
        else {
            this.request();
        }
    }

なるほど。ではこの正規表現をそのまま使えばはてなIDにヒットするってことになるわけですね。
それにしても、ソースが唯一の公式ドキュメントっていうのはどうなのよ。さすがはてな

追記

これまでユーザー名で使用可能な文字数の上限は半角英数字で15文字でしたが、32文字までご使用いただけるようになりました。

はてなのユーザー登録システムを刷新しました - はてなダイアリー日記

早速変えてるんじゃない!どうしてくれるwwww
ちなみに今は上のスクリプトよりももう少し洗練された実装になってます。

    checkUsername: function() {
        var usernameElement = document.getElementById('username-text');
        var username = usernameElement.value;
        this.initializeMessages();
        if ( username == '' ) {
            this.setError('NOT_BLANK');
        } else if ( username.length < 3 ) {
            this.setError('HATENA_NAME_LESS');
        } else if ( 32 < username.length ) {
            this.setError('HATENA_NAME_GREATER');
        } else if ( username.match(/hatena/i) ) {
            this.setError('HATENA_NAME_IGNORE');
        } else if ( username.match(/^(css|js|images|statics)$/i) ) {
            this.setError('HATENA_NAME_IGNORE');
        } else if ( username.match(/[^A-Za-z0-9\-\_]/) ){
            this.setError('HATENA_NAME_REGEX');
        } else if ( username.match(/^[^A-Za-z]/) ){
            this.setError('HATENA_NAME_FIRST_CHAR');
        } else if ( username.match(/[^A-Za-z0-9]$/) ){
            this.setError('HATENA_NAME_LAST_CHAR');
        } else {
            var xhr = new Ten.XHR('/'+username+'/status.json', { method: 'GET' }, this, 'recieveStatus' );
        }
        this.showMessages();
        usernameElement.focus();
    }