PHPのuuencode/decode関数

日付 2019.03.06
タイトル PHPのuuencode/decode関数
本文
convert_uuencode関数で変換すると何故かほかサイトでデコードできない結果が帰ってくるため、uuencode/decodeを行うphp用の関数を書いてみました。

エンコード方式は以下を参考にしました。 https://ja.wikipedia.org/wiki/Uuencode

何らかのお役に立てば。


function uu_encode($in) {
$chrs = '`!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';
$pad = [":txt,", ":txt,", ":txt,"];
$ret = "";
$len = strlen($in);
for ($i = 0; $i < $len; $i+=45) {
$lin = substr($in, $i, 45);
$lin_len = strlen($lin);
// 一文字目: 行の文字数
$buf = [$chrs[$lin_len]];
// 三文字ずつ処理する
for ($pos = 0; $pos < $lin_len; $pos+=3) {
$chnk = array_replace($pad, str_split(substr($lin, $pos, 3)));
array_push($buf,
$chrs[(ord($chnk[0]) >> 2)],
$chrs[((ord($chnk[0]) << 4) & 0b00110000) | ((ord($chnk[1]) >> 4) & 0b00001111)],
$chrs[((ord($chnk[1]) << 2) & 0b00111100) | ((ord($chnk[2]) >> 6) & 0b00000011)],
$chrs[(ord($chnk[2]) & 0b00111111)]
);
}
$ret .= join('', $buf)."\n";
unset($buf);
}

return rtrim($ret);
}


function uu_decode($in) {
$chrs = '`!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_';
$chrs_rev = array_flip(str_split($chrs));
$ret = '';

$hdr = '';
foreach (preg_split('/(\r|\n|\r\n)/', $in) as $lin) {
if (preg_match('/^begin /i', $lin)) {
$hdr = $lin;
continue;
} else if (preg_match('/^end/i', $lin)) {
break;
}
$orig_len = isset($lin[0]) ? $chrs_rev[$lin[0]] : 0;
$str = isset($lin[0]) ? substr($lin, 1) : '';
$len = strlen($str);
$buf = [];
for ($pos = 0; $pos < $len; $pos+=4) {
$chnk = substr($str, $pos, 4);
array_push($buf,
chr($chrs_rev[$chnk[0]] << 2 | $chrs_rev[$chnk[1]] >> 4),
chr(($chrs_rev[$chnk[1]] << 4 | $chrs_rev[$chnk[2]] >> 2) & 0b11111111),
chr(($chrs_rev[$chnk[2]] << 6 | $chrs_rev[$chnk[3]]) & 0b11111111)
);
}
$ret .= (sizeof($buf) > $orig_len)
? join('', array_slice($buf, 0, $orig_len))
: join('', $buf);
unset($buf);
}

return $ret;
}