<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>程默的博客 &#187; xxencode</title>
	<atom:link href="http://blog.chacuo.net/tag/xxencode/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.chacuo.net</link>
	<description>web原理、web架构、web安全、web性能、服务器性能、服务器架构、服务器安全;你不能预知明天，但你可以利用今天。你不能样样顺利，但你可以事事尽力!</description>
	<lastBuildDate>Mon, 31 Aug 2020 15:33:40 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>XXencode 编码，XX编码介绍、XXencode编码转换原理、算法</title>
		<link>http://blog.chacuo.net/778.html</link>
		<comments>http://blog.chacuo.net/778.html#comments</comments>
		<pubDate>Fri, 02 Aug 2013 11:08:32 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[xxencode]]></category>
		<category><![CDATA[字符编码]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=778</guid>
		<description><![CDATA[Xxencode编码，也是一个二进制字符转换为普通打印字符方法。跟UUencode编码原理方法很相似，唯独不同 [...]]]></description>
				<content:encoded><![CDATA[<p>Xxencode编码，也是一个二进制字符转换为普通打印字符方法。跟<a title="UUencode编码原理" href="http://blog.chacuo.net/753.html" target="_blank">UUencode编码原理</a>方法很相似，唯独不同的是可打印字符不同。通个UUencode编码，我们知道它有个缺点就是，64个可打印字符中，有很多的特殊字符。而XXencode编码方法，对64个原字符有做规范。这里它有跟Base64类型了。都有指定可打印字符范围、及编号。Xxencode编码在上世纪后期，IBM大型机中得到很广泛的应用。现在逐渐被Base64编码转换方法所取代了。</p>
<p><strong>Xxencode编码原理</strong></p>
<p>XXencode将输入文本以每三个字节为单位进行编码。如果最后剩下的资料少于三个字节，不够的部份用零补齐。这三个字节共有24个Bit，以6bit为单位分为4个组，每个组以十进制来表示所出现的数值只会落在0到63之间。以所对应值的位置字符代替。它所选择的可打印字符是：+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz，一共64个字符。跟base64打印字符相比，就是uuencode多一个“-” 字符，少一个&#8221;/” 字符。 但是，它里面字符顺序与Base64完全不一样。与UUencode比较，这里面所选择字符，都是常见字符，没有特殊字符。这也决定它当年流行使用原因！</p>
<p>每60个编码输出（相当于45个输入字节）将输出为独立的一行，每行的开头会加上<b>长度字符</b>，除了最后一行之外，长度字符都应该是“h”这个字符（<b>45，刚好是64字符中，第45位&#8217;h’字符</b>），最后一行的长度字符为<b>剩下的字节数目</b> 在64字符中位置所代表字符。</p>
<p><strong>问题：</strong>uuencode编码转换为xxencode编码怎么样操作？</p>
<p>从2中编码原理来看，几乎一样。就是所用的64个字符不一样。一次，简单对uuencode转换后字符，逐位（处理’`’字符)减去32，然后得到一个值。这个值在xxencode 64字符中所对应位置字符替换即可。</p>
<p><strong>XXencode编码转换过程</strong></p>
<blockquote><pre>    <table class="table" border="1" rules="all" cellspacing="0" width="80%" align="center"><tbody><tr><td>原始字符 </td><td colspan="8">C </td><td colspan="8">a </td><td colspan="8">t </td></tr><tr><td>原始ASCII码（十进制） </td><td colspan="8">67 </td><td colspan="8">97 </td><td colspan="8">116 </td></tr><tr><td>ASCII码（二进制） </td><td>0 </td><td>1 </td><td>0 </td><td>0 </td><td>0 </td><td>0 </td><td>1 </td><td>1 </td><td>0 </td><td>1 </td><td>1 </td><td>0 </td><td>0 </td><td>0 </td><td>0 </td><td>1 </td><td>0 </td><td>1 </td><td>1 </td><td>1 </td><td>0 </td><td>1 </td><td>0 </td><td>0 </td></tr><tr><td>新的十进制数值 </td><td colspan="6">16 </td><td colspan="6">54 </td><td colspan="6">5 </td><td colspan="6">52 </td></tr><tr><td>编码后的XXencode字符 </td><td colspan="6">E</td><td colspan="6">q</td><td colspan="6">3 </td><td colspan="6">O</td></tr></tbody></table></pre>
<pre>字符串：'Cat‘ 编码后是：Eq3O</pre>
</blockquote>
<pre><strong>XXencode编码PHP实现过程</strong></pre>
<blockquote><pre class="brush: php; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: true; smart-tabs: true; tab-size: 4; toolbar: true;">/**
 *xxencode编码*
 *@author 程默
 *@copyright http://blog.chacuo.net/
 *@param string $src 待处理字符串
 *@return string encode编码完字符串
 */
function c_xx_encode($src)
{
	//64个可打印字符
	static $base="+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    ///每次读取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&lt;$snum;$i++)
    {
        ////读取3个字节
        $_arr = array_map('ord',str_split(substr($src,$i*$lbyte,$lbyte)));
 
        ///计算每一个6位值
        $_dec = array();
        $_dec[]=$_arr[0]&gt;&gt;2;
        $_dec[]=(($_arr[0]&amp;3)&lt;&lt;4)|($_arr[1]&gt;&gt;4);
        $_dec[]=(($_arr[1]&amp;0xF)&lt;&lt;2)|($_arr[2]&gt;&gt;6);
        $_dec[]=$_arr[2]&amp;63;
         
        ///求每一位值，在64字符中所对应的字符
        foreach ($_dec as &amp;$v)
        {
           $v=$base[$v];
        }
        $desc = array_merge($desc,$_dec);
    }
     

    //每60个编码输出（相当于45个输入字节）将输出为独立的一行，每行的开头会加上长度字符，除了最后一行之外，长度字符都应该是'h'这个ASCII字符（45），最后一行的长度字符为剩下的字节数目,在64字符中对应字符。
    $abyte = 60;
    $crlf = "\r\n";
    $alen = count($desc);
    $anum = floor($alen/$abyte);
    $amod = ($alen%$abyte);
     
    $adesc = array();
     
    for ($i=0;$i&lt;$anum;$i++)
    {
        $adesc[]='h'.implode('',array_slice($desc,$i*$abyte,$abyte)).$crlf;
    }
     
    ///截取后面剩余数组长度
    if($amod!==0)
    {
        ///以下计算不满45字节编码情况
        $adesc[]=$base[$amod/4*$lbyte+($smod?$smod-$lbyte:$smod)].implode('',array_slice($desc,-$amod)).$crlf;
    }
     
    return implode('',$adesc);  
}</pre>
</blockquote>
<p>以上代码从uuencode编码做简单修改而来，基本上去掉+32一些地方。知道编码原理，其实我们很容易实现uuencode-&gt;xxencode转换的</p>
<blockquote>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/08/image2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="xxencode编码" border="0" alt="xxencode编码" src="http://blog.chacuo.net/wp-content/uploads/2013/08/image_thumb2.png" width="821" height="311"></a> </p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/08/image3.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="xxencode编码" border="0" alt="xxencode编码" src="http://blog.chacuo.net/wp-content/uploads/2013/08/image_thumb3.png" width="821" height="405"></a> </p>
<p>以上转换后结果，与专业转换工具一致的。好了，通过学习这类用可打印字符表示二进制字节的编码方法。我们可以发现很多有趣东西！对应以后我们如果做自己的编码转换，可以给我们很多借鉴！欢迎朋友们给出自己的意见！</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/778.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
