UUencode编码,UU编码介绍、UUencode编码转换原理与算法
UUencode编码起先⽤在unix⽹络中,先是Unix系统下将⼆进制的资料借由uucp邮件系统传输的⼀个编码程式,也是⼀种⼆进制到⽂字的编码。不属于MIME编码中⼀员。它也是定义了⽤可打印字符表⽰⼆进制⽂字⼀种⽅法,并不是⼀种新的编码集合。主要解决,⼆进制字符在传输、存储中问题。它早期在电⼦邮件中使⽤较多,最近这些年来基本上被MIME 中Base64所取代了。E-mail中⼀般采⽤UU、MIME、BINHEX三种编码标准! 我想,了解下这种编码将⼆进制字符转换为可打印字符实现思路!对我们以后做类似处理⼯作,应该会有很多的启⽰。
UUencode编码过程
Uuencode将输⼊资料以每三个字节为单位进⾏编码,如此重复进⾏。如果最后剩下的资料少于三个字节,不够的部份⽤零补齐。这三个字节共有24个Bit,以6-bit为单位分为4个组,每个组以⼗进制来表⽰所出现的数值只会落在0到63之间。将每个数加上32,所产⽣的结果刚好落在ASCII字符集中可打印字符(32-空⽩…95-底线)的范围之中。每60个编码输出(相当于45个输⼊字节)将输出为独⽴的⼀⾏,每⾏的开头会加上长度字符,除了最后⼀⾏之外,长度字符都应该是'M'这个ASCII字符(77=32+45),最后⼀⾏的长度字符为32+剩下的字节数⽬这个ASCII字符。如果是⼀个 0字节那它应该被转换为0×60⽽不是0×20,因为(前引⽤'`')优于 0×20(空格' ‘)。
特点⼀:看到特点了吧,也是64字符,也是⼀组6位。怎么,怎么,跟我们的base64这么相似呢?是的,从这个定义中,我们确实发现它跟base64⽐起来很相似了。
特点⼆:它定义64字符,不⽤写映射表,是通过加32转换到可打印字符范围中。⽐起base64,更为简单!
思考问题:它的字符范围都是可打印字符,我们会发现64字符集合中,有很多是特殊字符:”!”#¥%&‘()*+='” 等等。这些字符在不同应⽤中,可能都有些特殊⽤途。因此,在使⽤该编码时候,或许会出现⼀些问题。我想这也许是UUencode编码⽅法,逐渐被Base64所取代的原因吧。
UUencode 64字符集
可打印字符⼗进制ASCII值uuencode
⼆进制表⽰
uuencode
⼗进制表⽰
可打印字符⼗进制ASCII值
uuencode
⼆进制表⽰
uuencode
⼗进制表⽰
(space)32000 0000@64100 00032 !33000 0011A65100 00133 "34000 0102B66100 01034 #35000 0113C67100 01135 $36000 1004D68100 10036 %37000 1015E69100 10137 &38000 1106F70100 11038 '39000 1117G71100 11139 (40001 0008H72101 00040 )41001 0019I73101 00141 *42001 01010J74101 01042 +43001 01111K75101 01143 ,44001 10012L76101 10044 -45001 10113M77101 10145 .46001 11014N78101 11046 /47001 11115O79101 11147 048010 00016P80110 00048 149010 00117Q81110 00149 250010 01018R82110 01050 351010 01119S83110 01151 452010 10020T84110 10052 553010 10121U85110 10153 654010 11022V86110 11054 755010 11123W87110 11155 856011 00024X88111 00056 957011 00125Y89111 00157 :58011 01026Z90111 01058 ;59011 01127[91111 01159 <60011 10028\92111 10060 =61011 10129]93111 10161 >62011 11030^94111 11062 63011 11131_95111 11163
`96(1) 000 00064 UUencode编码转换过程
原始字符C a t
原始ASCII码(⼗进制)6797116
ASCII码(⼆进制)010000110110000101110100
新的⼗进制数值1654552
二进制编码转换+3248863784
编码后的Uuencode字符0V%T
字符串:'Cat‘ 编码后是:oV%T
UUencode PHP实现过程
编码转换过程,与Base64类似!下⾯代码是实现过程,我们可以看看转换⽅法!
/**
*uuencode编码*
*@author 程默
*@copyright blog.chacuo/
*@param string $src 待处理字符串
*@return string encode编码完字符串
*/
function c_uu_encode($src)
{
///每次读取3个字节
$lbyte = 3;
////将原始的3个字节转换为4个字节
$slen=strlen($src);
$smod = ($slen%$lbyte);
$snum = floor($slen/$lbyte);
$desc = array();
//将剩下字节以0字节补齐
$src = $smod===0?$src:$src.str_repeat("\0",$lbyte-$smod);
$snum = $smod===0?$snum:$snum+1;
for($i=0;$i<$snum;$i++)
{
////读取3个字节
$_arr = array_map('ord',str_split(substr($src,$i*$lbyte,$lbyte)));
///计算每⼀个6位值
$_dec = array();
$_dec[]=$_arr[0]>>2;
$_dec[]=(($_arr[0]&3)<<4)|($_arr[1]>>4);
$_dec[]=(($_arr[1]&0xF)<<2)|($_arr[2]>>6);
$_dec[]=$_arr[2]&63;
///对每个6位值加上32,读取ascii码如果6位值是0,以字符"`"代替
foreach ($_dec as &$v)
{
$v = $v===0?'`':chr($v+32);
}
$desc = array_merge($desc,$_dec);
}
//return implode('',$desc);
///以上代码只是进⾏转换,没有进⼀步进⾏
//每60个编码输出(相当于45个输⼊字节)将输出为独⽴的⼀⾏,每⾏的开头会加上长度字符,除了最后⼀⾏之外,长度字符都应该是'M'这个ASCII字符(77=32+45),最后⼀⾏的长度字符为32+剩下的字节数⽬这个ASCII字符。 $abyte = 60;
$crlf = "\r\n";
$alen = count($desc);
$anum = floor($alen/$abyte);
$amod = ($alen%$abyte);
$adesc = array();
for ($i=0;$i<$anum;$i++)
{
$adesc[]='M'.implode('',array_slice($desc,$i*$abyte,$abyte)).$crlf;
}
///截取后⾯剩余数组长度
if($amod!==0)
{
///以下计算不满45字节编码情况
$adesc[]=chr($amod/4*3+32+($smod?$smod-$lbyte:$smod)).implode('',array_slice($desc,-$amod)).$crlf;
}
return implode('',$adesc);
}
以上只是按照转换过程,通过PHP代码实现⽅法!⽬前PHP没有UUencode转换模块!
该代码转换结果,跟使⽤⼯具转换结果⼀致。我查看了线上⼀些转换⽅法,很多结果不⼀致!最好,⼤家使⽤在线⼯具转换前,做⼀下⽐较!没有做过验证的代码,可能会给你带来⿇烦!欢迎分享你的⽅法!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论