PPT

情報処理Ⅱ
2006年12月22日(金)
本日学ぶこと:プログラミングの例題2つ

暗号化・復号


文字列の書き換え


学ぶこと:構造体の利用,写像としての配列,static変数
学ぶこと:関数呼び出しによる文字列操作,ライブラリ関数の
活用
統合開発環境(Eclipse)
Wagahai Ha Nekodearu
tarako
Sioieid Ei Wyjgayipr
takehiko
2
IDE

Integrated Development Environmentの略,
統合開発環境とも呼ばれる.


エディタ,コンパイラ,デバッガなど,プログラミングに必要な
ツールが一つのインターフェースで統合して扱えるような環
境のこと.


ハードディスクのIDEは,Integrated Drive
Electronicsの略
デバッガとは…プログラムの不具合(バグ)の発見や修正を支
援するソフトウェア.Linuxではgdbコマンドが利用可能.
IDEの例:Eclipse,Visual C++,Turbo C++ など
3
Eclipse




オープンソースの統合開発環境
もともとIBMが開発したもので,現在は
Eclipse Foundationが開発・管理している.
プラグインにより機能を付加できる.
Javaに限らず様々なプログラミング言語の開発に利用可能


情報処理Ⅲで利用されている.
自宅で使いたい人へ


All-in-one Eclipseがおすすめ
コンパイラ・デバッガは別途インストールしなければならない
4
暗号化問題

仕様




入力文にあるすべての'A'をα,すべての'B'をβ,…に置き換
えて出力する.(単一換字暗号という.)
文字は,char型の任意の値とする.ただし'\0'を除く.
どの文字をどの文字に置き換えるかは,プログラムの中で指
定する.
簡単な操作で,復号できるようにする.
Wagahai Ha Nekodearu
•
暗号化
•
復号
Sioieid Ei Wyjgayipr
5
暗号化問題

(まずい)方針

'A'をα,'B'をβ,…に置き換えるのを
switch~caseで行う.
• プログラムが無駄に長くなる.
• 柔軟性に欠ける.
char encrypt_char(char c)
{
switch (c) {
case 'A':
return 'D';
case 'B':
return 'E';
...
}
}
6
変換前 変換後
暗号化問題

方針
 暗号化のための変換表(暗号化表)を,
配列で保持する.
• char encrypt_table[256];
'A'
'D'
'B'
'E'
...
...
encrypt_table['A']の値
encrypt_
table
… 'D'
+0
'E'
+'A'
+1
'F'
'G' …
+'C'
+'B'
+'D'
+255
7
暗号化問題

方針(続き)


暗号化は,写像を用いる.
• a = 'A'; のとき,b = encrypt_table[a]; でbの
値が'I'となるようにするには,あらかじめ
encrypt_table['A']の値を'I'としておけばよい.
復号のための変換表(復号表)は,逆写像を用いて求める.
• char decrypt_table[256];
• decrypt_table[encrypt_table['A']] = 'A';
gがfの逆写像
であるとは,
g(f(x))=x
8
暗号化問題

方針(続き)


fが恒等写像
であるとは,
f(x)=x
定義する関数
• 変換表を恒等写像にする.
• 暗号化表を設定する.
• 暗号化表を用いて,復号表を設定する.
• 変換表を用いて,文字列を暗号化もしくは復号する.
暗号化と復号はどう区別する?
• 暗号化:./encrypt Wakagai Ha Nekodearu
• 復号: ./encrypt -d Sioieid Ei Wyjgayipr
コマンドラインオプション
9
定義する構造体

typedef struct edtable {
char encrypt_table[256];
char decrypt_table[256];
} edtable;

暗号化(encryption)と復号(decryption)の表(table)
encrypt_table
decrypt_table
10
定義する関数(1)

void reset_table(edtable *table);

変換表を恒等写像にする.
table
encrypt_
table
?
0
?
1
… 'A'
?
'B'
?
'C'
? … 255
?
decrypt_
table
?
0
?
1
… 'A'
?
'B'
?
'C'
? … 255
?
11
定義する関数(2)

void set_encrypt_table(edtable *table,
const char *from, const char *to);

二つの文字列を用いて,暗号化表を設定する.
encrypt_
table
…
'I'
'F'
+'A'
table
'C' …
+'C'
+'B'
from
to
'A' 'B' 'C' … '\0'
'I' 'F' 'C' … '\0'
12
定義する関数(3)
void set_decrypt_table(edtable *table);

table

暗号化表を用いて,復号表を設定する.
decrypt_
table
…
+0
'A' …
+'A'
+1
encrypt_
table
+'B'
… 'I'
+0
+1
+'A'
+'I'
+255
…
+'B'
+'C'
+'D'
+255
13
定義する関数(4)

char *encrypt(const char *text, const
char *table);



変換表を用いて,文字列を暗号化もしくは復号する.
「暗号化」と「復号」の処理を共通化している!
戻り値は,変換された文字列で,static変数result(のポ
インタ値)となる.
text
table
result
戻り値
'W' 'a' 'g' 'a' 'h' 'a' 'i' '\0'
…
…
'S' 'i' 'o' 'i' 'e' 'i' 'd' '\0'
static領域(関数が終了しても,破棄されない)
14
暗号化プログラムの補足

関数set_encrypt_tableの仮引数from, toは
const char *型である.このとき



○ from++; to++;
× (*from)++;
• fromの参照先(const char型の値)を変更しようとして
いる.
暗号化のように,関数開始時点で長さがわからない文字列
を入力にとり,それと同じ長さの暗号文を返すときは,生成す
る暗号文が配列領域をはみ出さないように配慮する.

encrypt.cでは,100文字を越える入力は無視している.
15
文字列書き換え問題

仕様



3つの文字列を,コマンドライン引数にとる.
1番目の文字列の中に,2番目の文字列が含まれていれば,
それを3番目の文字列に置き換える.
例


「Wakayama City」が
./strrep tarako ra kehi
一つの引数
before: tarako
after: takehiko
./strrep 'Wakayama City' C Univers
before: Wakayama City
after: Wakayama University
16
文字列書き換え問題

mainで定義する変数




char *str_in = argv[1];
char *str_from = argv[2];
char *str_to = argv[3];
• argc >= 4 の確認を忘れずに.
char str[256];
• argv[1]のみでは,文字列を伸ばすこと
(tarako⇒takehiko)ができない.そこで,strに文字列
をコピーして,この配列を書き換える.
argv[1]
't' 'a' 'r' 'a' 'k' 'o' '\0'
str
't' 'a' 'r' 'a' 'k' 'o' '\0'
…
17
文字列書き換えの関数(1)

char *strrep(char *str, const char
*str_from, const char *str_to);
str
str_from
't' 'a' 'r' 'a' 'k' 'o' '\0'
…
'r' 'a' '\0'
書き換えられる
str_to
'k' 'e' 'h' 'i' '\0'
書き換えられない
18
文字列書き換えの関数(2)

関数内で使用する配列・ポインタ
str_from
str_to
str
'r' 'a' '\0'
'k' 'e' 'h' 'i' '\0'
't' 'a' 'r' 'a' 'k' 'o' '\0'
…
r
str_buf
't' 'a' 'r' 'a' 'k' 'o' '\0'
p
…
q
19
文字列書き換えの関数(3)

*r = '\0';
str_from
str_to
str
'r' 'a' '\0'
'k' 'e' 'h' 'i' '\0'
't' 'a' '\0' 'a' 'k' 'o' '\0'
…
r
str_buf
't' 'a' 'r' 'a' 'k' 'o' '\0'
p
…
q
20
文字列書き換えの関数(4)

strcat(r, str_to);
str_from
str_to
str
'r' 'a' '\0'
'k' 'e' 'h' 'i' '\0'
't' 'a' 'k' 'e' 'h' 'i' '\0'
…
r
str_buf
't' 'a' 'r' 'a' 'k' 'o' '\0'
p
…
q
21
文字列書き換えの関数(5)

strcat(str, q);
str_from
str_to
str
'r' 'a' '\0'
'k' 'e' 'h' 'i' '\0'
't' 'a' 'k' 'e' 'h' 'i' 'k' 'o' '\0' …
r
str_buf
't' 'a' 'r' 'a' 'k' 'o' '\0'
p
…
q
22
文字列書き換え関数の注意点

使用しているライブラリ関数







strcpy:文字列をコピーする※
strstr:文字列の中から文字列を見つける
strlen:文字列の長さを求める
strcat:文字列を連結(concatenate)する※
いずれも,第1引数が処理対象の文字列となる.
※最初の引数は文字配列を指すポインタとし,配列には,文字
列をコピー・連結しても大丈夫な領域を持たせておく.
rが文字列の先頭のとき,str_toやqが空文字列のときも,
関数strrepで問題なく書き換えられる.


./strrep Okayama O Wa
./strrep takehiko kehi ''
23
今後の予定

第12回:2007年1月19日(金)




授業開始時に第2回レポートを提出すること.
第13回:1月26日(金)
第14回:2月2日(金)
試験:試験期間中に実施する.掲示板を参照のこと.

「Cの書籍1冊」と「自筆ノート1冊」の持ち込みを認める.
24