PowerPoint プレゼンテーション

Similar documents
PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

PowerPoint プレゼンテーション

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

ポインタ変数

Microsoft PowerPoint - 11.pptx

PowerPoint Presentation

Microsoft Word - 3new.doc

Microsoft PowerPoint - 計算機言語 第7回.ppt

Microsoft Word - no15.docx

PowerPoint プレゼンテーション

Prog1_10th

情報工学実験 C コンパイラ第 2 回説明資料 (2017 年度 ) 担当 : 笹倉 佐藤

< F2D837C E95CF CF68A4A94C5816A2E6A>

memo

コマンドラインから受け取った文字列の大文字と小文字を変換するプログラムを作成せよ 入力は 1 バイトの表示文字とし アルファベット文字以外は変換しない 1. #include <stdio.h> 2. #include <ctype.h> /*troupper,islower,isupper,tol

memo

Microsoft Word - no11.docx

Microsoft PowerPoint - prog03.ppt

Microsoft PowerPoint - w5.pptx

<4D F736F F D20438CBE8CEA8D758DC F0939A82C282AB2E646F63>

PowerPoint プレゼンテーション

02: 変数と標準入出力

ポインタ変数

ファイル入出力

ゲームエンジンの構成要素

PowerPoint プレゼンテーション

Microsoft PowerPoint - 5Chap15.ppt

メソッドのまとめ

Microsoft PowerPoint - prog08.ppt

文字列 2 前回の授業ではコンピュータ内部での文字の取り扱い 文字型の変数 文字型変数への代入方法などを学習した 今回は 前回に引き続き 文字処理を学習する 内容は 標準入出力 ( キーボード ディスプレイ ) での文字処理 文字のファイル処理 文字を取り扱うライブラリ関数である 標準入出力 Lin

cp-7. 配列

ポインタ変数

program7app.ppt

02: 変数と標準入出力

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

プログラミング実習I

Microsoft PowerPoint - prog03.ppt

今回のプログラミングの課題 ( 前回の課題で取り上げた )data.txt の要素をソートして sorted.txt というファイルに書出す ソート (sort) とは : 数の場合 小さいものから大きなもの ( 昇順 ) もしくは 大きなものから小さなもの ( 降順 ) になるよう 並び替えること

ポインタ変数

Microsoft PowerPoint - C言語の復習(配布用).ppt [互換モード]

Prog1_12th

2006年10月5日(木)実施

memo

Microsoft Word - no103.docx

Microsoft PowerPoint - lec10.ppt

Microsoft PowerPoint - CproNt02.ppt [互換モード]

第1回 プログラミング演習3 センサーアプリケーション

PowerPoint Presentation

Microsoft PowerPoint - å®�æ−•è©¦é¨fi3ㆮ対ç�Œ.pptx

ファイル入出力

PowerPoint プレゼンテーション

02: 変数と標準入出力

Taro-再帰関数Ⅲ(公開版).jtd

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

Microsoft PowerPoint - kougi9.ppt

Microsoft PowerPoint - prog04.ppt

02: 変数と標準入出力

gengo1-11

Taro-ファイル処理(公開版).jtd

Microsoft PowerPoint - kougi6.ppt

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

CプログラミングI

Microsoft Word - no12.doc

ポインタ変数

Microsoft PowerPoint - prog06.ppt

デジタル表現論・第6回

演算増幅器

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

PowerPoint Presentation

Microsoft PowerPoint - prog07.ppt

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

関数の呼び出し ( 選択ソート ) 選択ソートのプログラム (findminvalue, findandreplace ができているとする ) #include <stdiu.h> #define InFile "data.txt" #define OutFile "surted.txt" #def

7 ポインタ (P.61) ポインタを使うと, メモリ上のデータを直接操作することができる. 例えばデータの変更 やコピーなどが簡単にできる. また処理が高速になる. 7.1 ポインタの概念 変数を次のように宣言すると, int num; メモリにその領域が確保される. 仮にその開始のアドレスを 1

第9回 配列(array)型の変数

講習No.9

文字数は1~6なので 同じ本数の枝を持つパスで生成される呪文の長さは最大で6 倍の差がある 例えば 上図のようなケースを考える 1サイクル終了した時点では スター節点のところに最強呪文として aaaaaac が求まる しかしながら サイクルを繰り返していくと やがてスター節点のところに aaaaaa

02: 変数と標準入出力

情報処理演習 B8クラス

関数の動作 / printhw(); 7 printf(" n"); printhw(); printf("############ n"); 4 printhw(); 5 関数の作り方 ( 関数名 ) 戻り値 ( 後述 ) void である. 関数名 (

Microsoft PowerPoint - 第3回目.ppt [互換モード]

memo


slide5.pptx

Microsoft PowerPoint - 13.ppt [互換モード]

プログラミング基礎

gengo1-12

今までの復習 プログラムで最低限必要なもの 入力 ( キーボードから ファイルから ) 出力 ( 画面へ ファイルへ ) 条件分岐 : 条件の成立 不成立により 異なる動作をする 繰り返し : 一定の回数の繰返し 条件成立の間の繰返し 関数の定義 関数の呼び出し C ではそれ以外に ポインタ データ

PowerPoint プレゼンテーション

プログラミングI第5回

Microsoft Word - Cプログラミング演習(8)

Taro-再帰関数Ⅱ(公開版).jtd

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

Microsoft Word - Training10_プリプロセッサ.docx

C 言語の式と文 C 言語の文 ( 関数の呼び出し ) printf("hello, n"); 式 a a+4 a++ a = 7 関数名関数の引数セミコロン 3 < a "hello" printf("hello") 関数の引数は () で囲み, 中に式を書く. 文 ( 式文 ) は

画像ファイルを扱う これまでに学んだ条件分岐, 繰り返し, 配列, ファイル入出力を使って, 画像を扱うプログラムにチャレンジしてみよう

Microsoft PowerPoint - C4(反復for).ppt

* ライブラリ関数 islower(),toupper() を使ったプログラム 1 /* 2 Program : trupper.c 3 Student-ID : K 4 Author : TOUME, Kouta 5 Comments : Used Library function i

Taro-リストⅢ(公開版).jtd

Transcription:

プログラミング応用演習 第 2 回文字列とポインタ

先週のパズルの解説 答え : 全部 p a 1 図の書き方 : p+1 は式であって その値を格納する記憶場所を考えないので 四角で囲まない 2 p+1 同じものを表すいろいろな書き方をしてみましたが パズル以上の意味はありません プログラム中に書くときは p+1 が短くていいんじゃないかな p+1 は 2 の記憶場所 p[1] は 2 に格納されている値 したがって &p[1] は 2 の記憶場所 すなわち p+1 に同じ *p は 1 に格納されている値 &*p は 1 の記憶場所 すなわち p に同じ したがって (&*p)+1 は p+1 に同じ *(p+1) は 2 に格納されている値 したがって &*(p+1) は 2 の記憶場所 すなわち p+1 に同じ p[0] は 1 に格納されている値 &p[0] は 1 の記憶場所 すなわち p に同じ したがって &p[0]+1 は p+1 に同じ

今日のお題 ポインタの利用例 文字列の操作などにポインタを使ってみる 題材として ( 情報セキュリティ学科っぽく ) 暗号化するプログラム 暗号を破るプログラムを考えます

復習 : 文字列 C 言語では 文字列は文字の配列 最後に \0( ヌル文字 ) がある 文字を表す型が char なので 文字列は char の配列 文字列定数は "( ダブルクォート ) で括って表す文字 文字コードという整数値に対応している 文字を整数として計算したり比較したりできる 文字コードを計算 比較している 文字定数は '( シングルクォート ) で括って表す アルファベットは文字コード中で並んでいる 例えば 'A'+1 は 'B' に等しい

復習 : ポインタと配列 配列の名前は 先頭の要素へのポインタ値を表す 例 ) char s[10]; と宣言したとき s は s[0] の記憶場所を表す 配列の要素はメモリ中で連続している 例 ) char s[10]; と宣言したとき s[0], s[1], s[2]... の記憶場所は連続している ポインタへの整数の加減算は 配列の添字の加減算に対応する 例 )char s[10],*p=s; と宣言 ( と初期代入 ) したとき p+1 は s[1] の記憶場所を p+2 は s[2] の記憶場所をそれぞれ表す

文字列の入力 scanf は 入力文字列を空白で区切ってしまう 便利なこともあるが 機能が多過ぎて使い勝手が悪いこともある 入力された空白や改行を そのまま文字列として読み込むには fgets を使う stdio.h で定義される構造体 char* fgets(char *s, int size, FILE *stream); 入力文字列を格納する記憶場所 入力文字列の最大長さ ( 最後のヌル文字を含む ) 入力元のファイル 標準入力の場合 stdin を指定する

シーザー暗号 文字列と 0~25 の整数を引数に受取り 文字列中のすべての英字を アルファベット順で与えられた数だけ後ろの英字に置き換えて得られる文字列に変換する関数を考える Z の次は A に循環するものとする 例 ) "Hello World!", 5 "Mjqqt Btwqi!"

例 ) 文字列中の英字を k 個ずらす関数 文字の配列を使った場合 配列だが 参照呼出し参照呼出しなので 中 ポインタを使った場合( 関数のみ ) なので 中身を書き換身を書き換えることが #include <stdio.h> えることができるできる #define MAXLEN 100 void caesar(char s[], int k) { int i; for(i=0 ; s[i]!= 0 ; i++) { if (('a'<=s[i])&&(s[i]<='z')) { s[i] = (s[i]-'a'+k)%26+'a'; else if (('A'<=s[i])&&(s[i]<='Z')) { int main() { s[i] = (s[i]-'a'+k)%26+'a'; char s[maxlen]; int k; fgets(s,maxlen,stdin); scanf("%d",&k); caesar(s,k); printf("%s",s); return 0; void caesar(char *s, int k) { char *p; for(p=s ; *p!= 0 ; p++) { if (('a'<= *p)&&(*p <='z')) { s p *p = (*p-'a'+k)%26+'a'; else if (('A'<= *p)&&(*p <='Z')) { *p = (*p-'a'+k)%26+'a';

シーザー暗号を破ってみる S vyfo Xkqkckus! この暗号文から鍵なしで平文が分かるか? シーザー暗号の暗号文は 鍵 ( 整数値 ) k に対して 26-k (mod 26) を鍵とする暗号化と同じ操作をすると 復号される 入力文字列に対して 26 通りの復号すべてを出力するプログラムを考えよう

文字列のコピーを要する 入力された暗号文を異なる鍵で何度も復号 ( 暗号化と同じ操作 ) するので 暗号文を毎回コピーすることを考える ( この問題の場合はコピーしない方法もありえますが ) 暗号を破るプログラムの全体像 : 文字列 ( 暗号文 ) を入力する 鍵を数え挙げる 鍵の一つを k として 以下を繰り返す : 入力文字列をコピーする コピーした文字列を鍵 k で復号する 得られた文字列を出力する

シーザー暗号を破るプログラム #include <stdio.h> #define MAXLEN 100 int main() { int k; char s[maxlen]; fgets(s,maxlen,stdin); for(k=0 ; k<26 ; k++) { char cp[maxlen],*src,*dst; src=s; dst=cp; while(*src!= 0) { 関数 caesar の定義 *dst = *src; dst++; src++; *dst=0; caesar(cp,(26-k)%26); printf("%s",cp); return 0; 鍵の数え挙げ s の内容を cp にコピー 鍵 k での暗号化に対応する復号の鍵 全通り行うので k でもよい おまけのパズル この while 文は C 言語だと while((*dst++=*src++)); と書ける ( セキュアコーディング的観点からはおすすめしない ) なぜ こう書けるか 分かりますか?

シーザー暗号の改造 文字列の他に N 個の整数値 k 0,k 1,...,k N-1 を受け取る 文字列の最初の文字 (0 文字目 ) を k 0 で暗号化し 次の文字 (1 文字目 ) を k 1 で暗号化し...N-1 文字目は k N-1 で暗号化する N 文字目以降の暗号化には 再び k 0 から順に使う 例 ) "Never give up!" を長さ 3 の鍵 5,7,3 で暗号化する : Never give up. 5 7 3 5 7 3 5 7 3 5 7 3 5 7 Slyjy lpyj xu. 文字列 ( 平文 ) と鍵の長さN, およびN 個の整数値を受け取ると 上記の暗号化を行って得られる文字列を出力するプログラムを考えよう

改造版シーザー暗号 鍵が配列 #include <stdio.h> #define MAXLEN 100 #define MAXKEY 6 void caesar2(char *s, int N, int *key){ int ki=0; char *p; for(p=s ; *p!= 0 ; p++) { int k = key[ki]; if (('a'<= *p)&&(*p <='z')) { *p = (*p-'a'+k)%26+'a'; else if (('A'<= *p)&&(*p <='Z')) { *p = (*p-'a'+k)%26+'a'; ki=(ki+1)%n; 鍵の ki 番目の値を使う int main() { int N,key[MAXKEY]; char s[maxlen]; int i; fgets(s,maxlen,stdin); scanf("%d",&n); if ((N < 1) (MAXKEY < N)) { printf("error\n"); return 1; for(i=0 ; i<n ; i++) { scanf("%d",key+i); caesar2(s,n,key); printf("%s",s); return 0; int の配列の要素へのポインタを渡す

改造版シーザー暗号を破ってみる 改造前と同様に全通り出力すればよい (?) N=2 では 26 2 =676 通り N=3 では 26 3 =17,576 通りこれくらいが 人間の目でみてチェックできる限界 平文の長さ 鍵の長さのときは そもそも破れない 暗号文と鍵の長さ (N) が入力されたとき 可能な平文を全通り出力するプログラムを考えよう

入力値 N に対して N 重ループが要る? 26 N 通りの鍵がありうる 0~25 の繰り返しを N 重にすれば全通りを数え挙げられる (?) N は入力値なので プログラムを書いている時点では分からない N 重ループのプログラムは書けない 例えば次のようなプログラミング方法がある : 1 0~26 N -1 の繰り返しをする 2 0~25 の繰り返しの中で再帰呼出しをする

改造版シーザー暗号を破ろうとするプログラム 1 #include <stdio.h> #define MAXLEN 100 #define MAXKEY 6 int power(int x, int y) { int i,r=1; for(i=0 ; i<y ; i++) { r *= x; return r; 関数 caesar2 の定義 x の y 乗の計算 int main() { char s[maxlen]; int N,key[MAXKEY]; int i,pk; fgets(s,maxlen,stdin); scanf("%d",&n); if ((N < 1) (MAXKEY < N)) { printf("error\n"); return 1; pk = power(26,n); for(i=0 ; i<pk ; i++) { char cp[maxlen]; int j,k=i; s を cp にコピーするコード for(j=0 ; j<n ; j++) { key[j] = k%26; k /= 26; caesar2(cp,n,key); printf("%s",cp); return 0; 鍵の数え挙げ i 番目の鍵を作る

改造版シーザー暗号を破ろうとするプログラム 2 #include <stdio.h> #define MAXLEN 100 #define MAXKEY 6 void keygen(int N, int n, int *key, char *s){ int i; if (n == N) { char cp[maxlen]; caesar2(cp,n,key); printf("%s",cp); return; for(i=0 ; i<26 ; i++) { 関数 caesar2 の定義 s を cp にコピーするコード key[n] = i; keygen(n,n+1,key,s); return; 再帰の終端で復号して表示 繰り返しの中で再帰呼出し int main() { char s[maxlen]; int N,key[MAXKEY]; fgets(s,maxlen,stdin); scanf("%d",&n); if ((N<1) (MAXKEY<N)) { printf("error\n"); return 1; keygen(n,0,key,s); return 0;

実験の仕方 : リダイレクトとパイプ こんなファイルを作る プログラムに入力する文字列を記述したもの 3 のあとの改行を忘れないように プログラムに入力する値を流し込む ( リダイレクト )./a.out < test Slyjy lpyj xu. 3 ファイルの名前は何でもよいが ここでは test としておく 出力を less コマンドに渡す ( パイプ )./a.out < test less

MAXKEY( 鍵の最大長さ ) を 6 にした理由 26 6 =308,915,776 < 2 31 =2,147,483,648 < 26 7 =8,031,810,176 なので 鍵の総数を 32bit の int で表すとすると 鍵の長さは最大 6 改造版シーザー暗号を破ろうとするプログラム 1 は 長さ 7 以上の鍵に対応していない 改造版シーザー暗号を破ろうとするプログラム 2 は 長さ 7 以上の鍵でも動く ただし 何億もの候補を提示されても人間はチェックできないので無意味

実行してみよう 以下の暗号を解読してください ただし 改造版シーザー暗号で鍵の長さが 2 と分かっている Ol h nelna wevtyntzle!

次回予告 構造体