Objective-C 入門指南 - 編碼

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




上圖是用了如下的表格
@"q", @"z", @"i", @"r", @"a",
@"j", @"s", @"b", @"k", @"t",
@"c", @"l", @"u", @"d", @"m",
@"v", @"e", @"n", @"w", @"f",
@"o", @"x", @"g", @"p", @"y", @"h"


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


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


所以需要利用一個迴圈 (loop) 進行上述編碼工作,逐一檢查 NSString 字串中的每一個元素,並將該元素轉換成字元 (character) ,若是屬於英文小寫字母的編碼範圍,在 ASCII 就是 97 到 122 之間,先將該字元轉換為整數,然後減掉 97 就會是表格中的對應字母。


這是說,第 0 個字元(索引值為 0 ) 'T' 不在英文小寫字母編碼的範圍,因此程式不會處理,然後到第 1 個字母 h ,這是英文小寫字母編碼為 84 ,減去 97 之後為 7 ,對應到上面的表格會是 @"b" ,因此得到的新字串第 1 個新字母就是 @"b" ,餘下會一直進行重複的工作到 NSString 字串結束為止。


因此,我們對編碼方法 (method) 設計如下
- (NSString *) toEncode: (NSString *) s
{
    NSString *r = @"";
    int number = [s length];
    char ct; 
    int i;
    
    for (i = 0;i < number;i++) {
        ct = [s characterAtIndex: i];
        
        if (ct >= 97 && ct <= 122) {
            r = [r stringByAppendingString: [cArray objectAtIndex: ct - 97]];
        }
        else {
            r = [r stringByAppendingFormat: @"%c", ct];
        }
    }
    
    return r;
}


toEncode: 接收一個 NSString 當參數,也回傳一個新 NSString 字串。進行編碼轉換的迴圈
for (i = 0;i < number;i++) {
    ct = [s characterAtIndex: i];
        
    if (ct >= 97 && ct <= 122) {
        r = [r stringByAppendingString: [cArray objectAtIndex: ct - 97]];
    }
    else {
        r = [r stringByAppendingFormat: @"%c", ct];
    }
}


number 為參數 s 的 length 回傳值 (return value) ,這是 NSString 的字串長度,因此這個迴圈只會檢查 s 中的每一個元素。留意這一行
ct = [s characterAtIndex: i];


NSString 的 characterAtIndex: 回傳索引值 i 的字元型態常數,這裡指派給變數 ct 。有了 ct 後,就可以判斷 ct 的值是否在 97 到 122 之間
if (ct >= 97 && ct <= 122) {


如果 ct 在 97 到 122 之間,就將 ct 減掉 97 當成密碼表 NSMutableArray 物件 (object) objectAtIndex: 的參數 (parameter) ,取得對應轉換的字母,然後把該字母附加到 r 的最後
r = [r stringByAppendingString: [cArray objectAtIndex: ct - 97]];


反之,如果 ct 並不在 97 到 122 之間,就直接將 ct 附加到 r 的最後
r = [r stringByAppendingFormat: @"%c", ct];


簡不簡單呢?記得將上面的 toEncode: 加到 Encrypt.m 裡面,然後我們用以下的 demo.m 來測試
int main(int argc, char *argv[]) 
{ 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
 Encrypt *e = [[Encrypt alloc] initRandomEncrypt];
 NSString *s = @"There is no spoon.";
    NSString *o = @"\n\n";
    o = [o stringByAppendingString: [e toEncode: s]];
    o = [o stringByAppendingString: @"\n\n"];
    NSLog(o);
 
    [pool drain];
    return 0;
}

/* 《程式語言教學誌》的範例程式
    http://pydoing.blogspot.com/
    檔名:demo.m
    功能:示範 Objective-C 程式 
    作者:張凱慶
    時間:西元 2012 年 7 月 */


Build and Go ,結果如下



我們對 "There is no spoon." 進行編碼,結果符合預期,接下來,我們繼續加入解碼的功能吧!


中英文術語對照
編碼encoding
字串string
迴圈loop
字元character
方法method
回傳值return value
物件object
參數parameter


您可以繼續參考
軟體開發


相關目錄
Objective-C 入門指南
Objective-C 教材
首頁



參考資料
Learning Objective-C: A Primer
The Objective-C Programming Language
Cocoa Fundamentals Guide
Coding Guidelines for Cocoa
Advanced Memory Management Programming Guide
Archives and Serializations Programming Guide

沒有留言: