読者です 読者をやめる 読者になる 読者になる

latest log

酩酊状態で書いたエンジニアポエムです。酩酊状態で読んでください。

話の流れで AKB48(), AKB48.decode() をガーッて。30分でガーッて作ってみたよ

(ε・◇・)з AKB48 って Base64 の亜種かなんかでしょ?
(ε・◇・)з でもちょっと余るんだな… 何個か抜かなきゃ…

(ε・◇・)з じゃあ A, K, B, 4, 8 と、恋愛禁止らしいので L, O, V, E も抜いちゃいますか!

Base64:
  ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
  ↓↓
AKB48:
    CD FGHIJ  MN PQRSTU WXYZ  cd fghij  mn pqrstu wxyz0123 567 9+/

(ε・◇・)з ガーッて書いてみたよ

// Usage:
//      var encoded = AKB48("おしめん");
//
//      console.log(encoded); // -> "pUCiQpUCjhpUDNDpUDPc"
//
//      AKB48.decode(encoded); // -> おしめん

var AKB48;

AKB48 || (function(global) {

global["AKB48"] = AKB48;
global["AKB48"].decode = AKB48_decode;

// === Another Kindness Base 48 ============================

// AKB48 - encode
function AKB48(data) { // @param String:
                       // @return UTF8AKB48String:
                       // @desc: encode String to UTF8 + AKB48 formated String
    function _UTF8ByteArray(data) {
        var rv = [], i = 0, iz = data.length, c = 0;

        for (; i < iz; ++i) {
            c = data.charCodeAt(i);
            if (c < 0x80) { // ASCII(0x00 ~ 0x7f)
                rv.push(c & 0x7f);
            } else if (c < 0x0800) {
                rv.push(((c >>>  6) & 0x1f) | 0xc0, (c & 0x3f) | 0x80);
            } else if (c < 0x10000) {
                rv.push(((c >>> 12) & 0x0f) | 0xe0,
                        ((c >>>  6) & 0x3f) | 0x80, (c & 0x3f) | 0x80);
            }
        }
        return rv;
    }

    AKB48._db || _initAKB48();

    var rv = [],
        ary = _UTF8ByteArray(data),
        c = 0, i = -1, iz = ary.length,
        pad = [0, 2, 1][iz % 3],
        chars = AKB48._db.chars;

    --iz;
    while (i < iz) {
        c = (ary[++i] << 16) | (ary[++i] << 8) | (ary[++i]); // 24bit
        rv.push(chars[(c >> 19) & 0x1f],
                chars[(c >> 14) & 0x1f],
                chars[(c >>  9) & 0x1f],
                chars[(c >>  4) & 0x1f],
                chars[ c        & 0x1f]);
    }
    pad > 1 && (rv[rv.length - 2] = "=");
    pad > 0 && (rv[rv.length - 1] = "=");

    return rv.join("");
}

// AKB48#decode
function AKB48_decode(data) { // @param UTF8AKB48String:
                              // @return String:
                              // @desc: decode UTF8 + AKB48 formated String

    function _UTF8Decode(byteArray) {
        var rv = [], ri = -1, i = 0, iz = byteArray.length, c = 0;

        for (; i < iz; ++i) {
            c = byteArray[i]; // first byte
            if (c < 0x80) { // ASCII(0x00 ~ 0x7f)
                rv[++ri] = c;
            } else if (c < 0xe0) {
                rv[++ri] = (c & 0x1f) <<  6 | (byteArray[++i] & 0x3f);
            } else if (c < 0xf0) {
                rv[++ri] = (c & 0x0f) << 12 | (byteArray[++i] & 0x3f) << 6
                                            | (byteArray[++i] & 0x3f);
            }
        }
        return String.fromCharCode.apply(null, rv);
    }

    AKB48._db || _initAKB48();

    var rv = [],
        c = 0, i = -1,
        ary = data.split(""),
        iz = data.length - 1,
        codes = AKB48._db.codes;

    while (i < iz) {                // 00000000|00000000|00000000 (24bit)
        c = (codes[ary[++i]] << 19) // 11111   |        |
          | (codes[ary[++i]] << 14) //      111|11      |
          | (codes[ary[++i]] <<  9) //         |  11111 |
          | (codes[ary[++i]] <<  4) //         |       1|1111
          |  codes[ary[++i]];       //         |        |    1111
                                    //    v        v        v
        rv.push((c >> 16) & 0xff,   // --------
                (c >>  8) & 0xff,   //          --------
                 c        & 0xff);  //                   --------
    }

    // cut tail
    rv.length -= [0, 0, 2, 1][data.replace(/\=+$/, "").length % 4];

    return _UTF8Decode(rv);
}

// inner - init AKB48
function _initAKB48() {
    var base = "CDFGHIJMNPQRSTUWXYZcdfghijmnpqrstuwxyz01235679+/",
        i = 0,
        db = {
            chars: base.split(""), // ["C", "D", ... "/"]
            codes: { "=": 0 }
        };

    for (; i < 48; ++i) {
        db.codes[base.charAt(i)] = i;
    }
    AKB48._db = db;
}

})(this);

(っ>﹏<)っ どこで使うんだろこれ…