PHP 入門指南 - 編碼

編碼 (encoding) 需要用到轉換表格,我們利用陣列 (array) 儲存這個表格,簡單說,就是利用英文字母的排列順序,相對到表格的對應關係




上圖是用了如下的表格
"qzirajsbktcludmvenwfoxgpyh"


對以下的字串 (string) 而言
"There is no spoon.";


我們先來想一想程式應該如何完成這一項工作,首先, 'T' 不是英文小寫字母,因此跳過,然後 'h' 、 'e' 、 'r' 、 'e' 都是英文小寫字母,對照表格,需要轉換為 'b' 、 'a' 、 'n' 、 'a' ,接下來遇到一個空格字元 ' ' ,也跳過,然後 'i' 、 's' 也都是英文小寫字母,需要轉換為 'k' 、 'w' ,餘下類推。


所以需要利用一個迴圈 (loop) 進行上述編碼工作,逐一檢查字串中的每一個元素,若是該元素為英文小寫字母,就開始進行編碼轉換,這是利用另外一個迴圈,檢查該元素於 oArray 中的索引值,最後利用該索引值取出 cArray 裡的元素。


這是說,第 0 個字元(索引值為 0 ) 'T' 不在英文小寫字母編碼的範圍,因此程式不會處理,然後到第 1 個字母 'h' ,這在 oArray 中索引值為 7 ,對照為 cArray 的 'b' ,因此 'h' 會轉換為 'b' 。


因此,編碼方法 (method) 設計如下
function toEncode($s) {
    $r = Array();
    $pattern = "/[a-z]/";
    for ($i = 0; $i < strlen($s); $i++) {
        if (preg_match($pattern, $s[$i])) {
            for ($j = 0; $j < 26; $j++) {   
                if ($s[$i] == $this->oArray[$j]) {
                    array_push($r, $this->cArray[$j]);
                    break;
                }
            }
        }            
        else {
            array_push($r, $s[$i]);
        }
    }
        
    return join($r); 
}


$r 為暫存結果的變數 (variable) ,這裡用空的陣列, $pattern 則是正規運算式 (regular expression) 的字串,這表示 a 到 z 所有英文小寫字母,然後外層迴圈
for ($i = 0; $i < strlen($s); $i++) {


strlen() 為內建函數,回傳字串長度,也就是字串中所有元素個數。底下的條件檢查
if (preg_match($pattern, $s[$i])) {


preg_match() 也是內建函數,用來檢查第二個參數是否符合第一個參數的正規運算式。


底下縮排的 array_push() 則會將第二個參數 (parameter) 加入第一個參數陣列中
array_push($r, $this->cArray[$j]);


最後回傳時先呼叫內建函數 join() ,將 $r 裡頭的所有元素連結成一個字串,所以 toEncode() 最後也是回傳字串
return join($r); 


我們把 encryptdemo2.php 修改如下
<?php
echo "<br / >";
$e = new Encrypt;
echo "code: ";
for ($i = 0; $i < 26; $i++) {
    echo $e->cArray[$i];
}
echo "<br / >";
echo "input : There is no spoon.<br / >";
echo "output: ".$e->toEncode("There is no spoon.");
echo "<br / ><br / >";

class Encrypt {
    public $cArray = Array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z");
    public $oArray = Array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z");

    function __construct() {
        shuffle($this->cArray);
    }
    
    function toEncode($s) {
        $r = Array();
        $pattern = "/[a-z]/";
        for ($i = 0; $i < strlen($s); $i++) {
            if (preg_match($pattern, $s[$i])) {
                for ($j = 0; $j < 26; $j++) {   
                    if ($s[$i] == $this->oArray[$j]) {
                        array_push($r, $this->cArray[$j]);
                        break;
                    }
                }
            }            
            else {
                array_push($r, $s[$i]);
            }
        }
        
        return join($r); 
    }
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:encryptdemo3.php
    功能:示範 PHP 程式 
    作者:張凱慶
    時間:西元 2012 年 11 月 */
?>


我們來看看結果吧



接下來,我們繼續建置解碼功能吧!


中英文術語對照
編碼encoding
陣列array
字串string
迴圈loop
方法method
變數variable
規則運算式regular expression
參數parameter


您可以繼續參考
網站篇


相關目錄
回 PHP 入門指南
回 PHP 教材
回首頁


參考資料
http://php.net/manual/en/language.oop5.php
http://www.php.net/manual/en/oop5.intro.php
http://www.php.net/manual/en/language.oop5.basic.php
http://php.net/manual/en/function.strlen.php
http://php.net/manual/en/function.preg-match.php
http://www.php.net/manual/en/function.join.php

2 則留言:

Unknown 提到...

preg_match() 也是內建函數,會將第二個參數 (parameter) 加入第一個參數陣列中

這個部分是不是有錯誤呢?
我查詢這個函數是代表條件符合還是不符合

上面應該是在解釋array_push()這個參數。

Kaiching Chang 提到...

這部份漏寫一句,已修改,感謝指正 :)