覚えてるロジック

  • ちょっとわかりやすく
  • ちょっとパディングを工夫
<?php
function b64($s)
{
    $t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';

    $res = '';

    for ($i = 0; $i < strlen($s); $i+=3) {
        $c1 = ord($s[$i]);
        $c2 = isset($s[$i + 1]) ? ord($s[$i + 1]) : 0;
        $c3 = isset($s[$i + 2]) ? ord($s[$i + 2]) : 0;

        $o1 =                      (($c1 >> 2) & 0x3f);
        $o2 =                      (($c1 << 4) & 0x30) | (($c2 >> 4) & 0x0f);
        $o3 = isset($s[$i + 1]) ? (                      (($c2 << 2) & 0x3c) | (($c3 >> 6) & 0x03)) : 64;
        $o4 = isset($s[$i + 2]) ? (                       ($c3     ) & 0x3f                       ) : 64;

        $res .= $t[$o1] . $t[$o2] . $t[$o3] . $t[$o4];
    }

    return $res;
}

$ss = array('abc', 'abcd', 'abcde', 'abcdef');

foreach ($ss as $s) {
    var_dump(b64($s));
    var_dump(base64_encode($s));
}

別ロジックを考える

  • 3文字単位じゃない処理
<?php
function b64($s)
{
    $t = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';

    $res = '';

    $b = 0;
    for ($i = 0; $i < strlen($s); $i++) {
        $c = ($b | (ord($s[$i]) >> ((($i % 3) + 1) * 2))) & 0x3f;
        $b = (ord($s[$i]) << (4 - (($i % 3) * 2))) & 0x3f;

        $res .= $t[$c];

        if ($i % 3 == 2) {
            $res .= $t[$b];
            $b = 0;
        }
    }
    if (strlen($res) % 4 > 0) {
        $res .= $t[$b] . str_repeat('=', 3 - (strlen($res) % 4));
    }

    return $res;
}

$ss = array('abc', 'abcd', 'abcde', 'abcdef');

foreach ($ss as $s) {
    var_dump(b64($s));
    var_dump(base64_encode($s));
}

  • Next