ローデンの独り言 https://rouden.jp
クリックでログアウト アクセスカウンター
Loading... try later!
RSSフィード

TypeScript 1.6 で Base64 encode/decode

TypeScriptでBase64変換するプログラムです。
	
elm200 の日記Javascript で Base64 encode/decodeで公開されているパブリックドメインなコードを勝手にTypeScriptに変換して使っていたのですが、他の用途にも使えそうだったので公開することにしました。

変更点は以下のとおりです。
 * TypeScript 1.6でビルドできるようにした。
 * 元のコードではグローバル変数lenに値が代入されることがあったので、var を追加した。

元の製作者リスペクトで、このコードのライセンスはpublic domain(著作権放棄)&無保証とします。

ダウンロードはこちら
/**
 * Base64 encoding
 * http://www.ietf.org/rfc/rfc2045.txt
 */
class Base64
{
    private symbols: string[] = [];
    private encodeMap: string[] = [];
    private decodeMap: { [id: string]: number } = {};
    public constructor()
    {
        this.initialize();
    }
    private initialize(): void
    {
        var startChar = "A".charCodeAt(0);
        for (var i = 0; i < 26; i++)
        {
            this.symbols.push(String.fromCharCode(startChar + i));
        }
        var startChar = "a".charCodeAt(0);
        for (var i = 0; i < 26; i++)
        {
            this.symbols.push(String.fromCharCode(startChar + i));
        }
        var startChar = "0".charCodeAt(0);
        for (var i = 0; i < 10; i++)
        {
            this.symbols.push(String.fromCharCode(startChar + i));
        }
        this.symbols.push("+", "/");
        this.encodeMap = [];
        for (var i = 0; i < this.symbols.length; i++)
        {
            this.encodeMap[i] = this.symbols[i];
        }
        this.decodeMap = {};
        for (var i = 0; i < this.symbols.length; i++)
        {
            this.decodeMap[this.symbols[i]] = i;
        }
        this.decodeMap["="] = null;
    }
    public encode(octets: number[]): string
    {
        var i: number, len: number;
        var map = this.encodeMap;
        var encoded: string[] = [];
        for (i = 0, len = Math.floor(octets.length / 3) * 3;
            i < len; i += 3)
        {
            var b0 = octets[i];
            var b1 = octets[i + 1];
            var b2 = octets[i + 2];
            var qs = map[(b0 >> 2) & 0x3f]
                + map[((b0 << 4) + (b1 >> 4)) & 0x3f]
                + map[((b1 << 2) + (b2 >> 6)) & 0x3f]
                + map[b2 & 0x3f];
            encoded.push(qs);
        }
        switch (octets.length % 3)
        {
            case 1:
                var b0 = octets[i];
                var qs = map[(b0 >> 2) & 0x3f]
                    + map[(b0 << 4) & 0x3f]
                    + "==";
                encoded.push(qs);
                break;
            case 2:
                var b0 = octets[i];
                var b1 = octets[i + 1];
                var qs = map[(b0 >> 2) & 0x3f]
                    + map[((b0 << 4) + (b1 >> 4)) & 0x3f]
                    + map[(b1 << 2) & 0x3f]
                    + "=";
                encoded.push(qs);
                break;
        }
        return encoded.join("");
    }
    public decode(encoded: string): number[]
    {
        if (encoded.length % 4 != 0)
        {
            throw "encoded.length must be a multiple of 4.";
        }
        var decoded: number[] = [];
        var map = this.decodeMap;
        for (var i = 0, len = encoded.length; i < len; i += 4)
        {
            var b0 = map[encoded[i]];
            var b1 = map[encoded[i + 1]];
            var b2 = map[encoded[i + 2]];
            var b3 = map[encoded[i + 3]];
            var d0 = ((b0 << 2) + (b1 >> 4)) & 0xff;
            decoded.push(d0);
            if (b2 == null) break; // encoded[i + 1] == "="
            var d1 = ((b1 << 4) + (b2 >> 2)) & 0xff;
            decoded.push(d1);
            if (b3 == null) break; // encoded[i + 2] == "="
            var d2 = ((b2 << 6) + b3) & 0xff;
            decoded.push(d2);
        }
        return decoded;
    }
    public uriEncodedToOctets(uriEncoded: string): number[]
    {
        var octets: number[] = [];
        for (var i = 0, len = uriEncoded.length; i < len; i++)
        {
            // Note that IE6 doesn't allow an expression like "uriEncoded[i]";
            var c = uriEncoded.charAt(i);
            var b: number;
            if (c == "%")
            {
                var hex = uriEncoded.charAt(++i) + uriEncoded.charAt(++i);
                b = parseInt(hex, 16);
            } else
            {
                b = c.charCodeAt(0);
            }
            octets.push(b);
        }
        return octets;
    }
    public encodeStringAsUTF8(utf8str: string): string
    {
        var uriEncoded = encodeURIComponent(utf8str);
        var octets = this.uriEncodedToOctets(uriEncoded);
        return this.encode(octets);
    }
    public octetsToUriEncoded(octets: number[]): string
    {
        var uriEncoded: string[] = [];
        for (var i = 0, len = octets.length; i < len; i++)
        {
            var hex = octets[i].toString(16);
            hex = ("0" + hex).substr(hex.length - 1, 2);
            uriEncoded.push("%" + hex);
        }
        return uriEncoded.join("");
    }
    public decodeStringAsUTF8(encoded: string): string
    {
        var octets = this.decode(encoded);
        var uriEncoded = this.octetsToUriEncoded(octets);
        return decodeURIComponent(uriEncoded);
    }
}
var base64:Base64 = new Base64();

最終更新: 2017/12/07 23:50
Message
これはエラーメッセージのテストです。長いメッセージが表示されるとどうなるでしょうか。
 OK