原始字符 | C | a | t | |||||||||||||||||||||
原始ASCII碼(十進制) | 67 | 97 | 116 | |||||||||||||||||||||
ASCII碼(二進制) | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 |
新的十進制數值 | 16 | 54 | 5 | 52 | ||||||||||||||||||||
編碼后的XXencode字符 | E | q | 3 | O |
XXencode編碼PHP實現過程
/** *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$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; ///求每一位值,在64字符中所對應的字符 foreach ($_dec as $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$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); }
以上代碼從uuencode編碼做簡單修改而來,基本上去掉+32一些地方。知道編碼原理,其實我們很容易實現uuencode->xxencode轉換的
以上轉換后結果,與專業轉換工具一致的。好了,通過學習這類用可打印字符表示二進制字節的編碼方法。我們可以發現很多有趣東西!對應以后我們如果做自己的編碼轉換,可以給我們很多借鑒!歡迎朋友們給出自己的意見!