[Mew-dist 05605] Re: b47
Shun-ichi GOTO
gotoh at example.com
1998年 7月 19日 (日) 02:45:50 JST
後藤@太陽計測です
>>>>> From: Kazu Yamamoto (山本和彦) <kazu at example.com>
kazu> さっきは時間がなかったので答えられませんでした。確かにちょっと分りにく
kazu> いですね。では解説を兼ねて、眠くなるための呪文を唱えてあげましょう。
なんだか面白そうなので、挑戦しました。
#え、マジにやるなって?
#眠くなるどころか、今日1日が充実してしまいました。
kazu> 100 点を取れる修士学生はどれくらい日本にいるか?
どんなもんスかねぇ (-_-;
P.S.
個人的にはSubject:は可能な限り可読であって欲しい。。。かな
--- Regards,
Shun-ichi Goto <gotoh at example.com>
R&D Group, TAIYO Corp., Tokyo, JAPAN
-------------- next part --------------
kazu> (問1) 下記の Subject: に対する最適な符号化を示し、その理由を述べよ。
kazu> ただし、"<o>" はウムラウト文字を表す。[10 点]
理由は省略 :-)
またFoldingは考慮していない
kazu> m<o>tley crue が好き
=?iso-8859-1?Q?m=F6tley?= crue =?iso-2022-jp?B?GyRCJCw5JSQtGyhC?=
kazu> m<o>tley crueが好き
=?iso-8859-1?Q?m=F6tley_crue?= =?iso-2022-jp?B?GyRCJCw5JSQtGyhC?=
or
=?iso-2022-jp-2?B?bRsuQRtOdnRsZXkgY3J1ZRskQiQsOSUkLRsoQg==?=
kazu> m<o>tley crue "が好き"
=?iso-8859-1?Q?m=F6tley?= crue =?iso-2022-jp?B?IhskQiQsOSUkLRsoQiI=?=
kazu> m<o>tley crue"が好き"
=?iso-8859-1?Q?m=F6tley_crue"?= =?iso-2022-jp?B?GyRCJCw5JSQtGyhCIg==?=
or
=?iso-2022-jp-2?B?bRsuQRtOdnRsZXkgY3J1ZSIbJEIkLDklJC0bKEIi?=
kazu> m<o>tley "crue が好き"
=?iso-8859-1?Q?m=F6tley?= "crue =?iso-2022-jp?B?GyRCJCw5JSQtGyhCIg==?=
-------------- next part --------------
kazu> (問2) 問1 で答えた符号化パターンを選択する評価アルゴリズムを示せ。[20点]
まず、field-bodyを「エンコード不要」な部分と「要エンコード」な部分に分割
することを考える。
これにあたり、RFC2047での空白の保存問題に着目する必要があるため、
まず、field-bodyの構成要素を、LWSPのみで構成される文字列SPACEと
それ以外の文字列で構成されるWORDで分割するものとする。WORDには
エンコード不要なAWORDとそれ以外のもの(エンコードが必要)EWORDとが
存在する。
以下のルール(yacc風)を順次適用しSPACE、AWORD、EWORDの並びを
APARTおよびEPARTの並びに変換する(ただし、BOLは行頭、EOLは行末を
あらわすものとする)。
この結果、EPARTとAPARTが単一か、あるいは交互に現れ、EPARTとAPARTの
隣接においては隣接部には必ずLWSPが保証される。
EPART : EWORD /* r.1 */
| AWORD EPART /* r.2 */
| EPART EPART /* r.3 */
| EPART SPACE EPART /* r.4 */
| BOL SPACE EPART /* r.5 */
| EPART SPACE EOL /* r.6 */
;
APART : BOL AWORD EOL /* r.7 */
| SPACE AWORD SPACE /* r.8 */
| APART SPACE AWORD SPACE /* r.9 */
| BOL SPACE APART /* r.10 */
| APART SPACE EOL /* r.11 */
;
field-bodyをEPARTとAPARTへ分割した後、EPARTのエンコードを行う。
エンコードには2つのルールがあり、iso-2022-jpとiso-8859-1を
単一のiso-2022-jp-2としてエンコードする方法と、個々にエンコードする
方法である。1つのEPARTを複数のencoded-wordに分割する際は
LWSPで区切る。
以上//
問1の例を元にこの操作を行った例を以下に示す。
(1) m<o>tley crue が好き
"m<o>tley" " " "crue" " " "が好き"
== EWORD SPACE AWORD SPACE EWORD
=> EPART SPACE AWORD SPACE EWORD /* r.1 */
=> EPART SPACE AWORD SPACE EPART /* r.1 */
=> EPART APART EPART /* r.8 */
== "m<o>tley" " crue " "が好き"
=> iso-8859-1 "m<o>tley"
ascii " crue "
iso-2022-jp "が好き"
=> "=?iso-8859-1?Q?m=F6tley?= crue =?iso-2022-jp?B?GyRCJCw5JSQtGyhC?="
(2) m<o>tley crueが好き
"m<o>tley crueが好き"
=> "m<o>tley" " " "crue" "が好き"
== EWORD SPACE AWORD EWORD
=> EPART SPACE AWORD EWORD /* r.1 */
=> EPART SPACE AWORD EPART /* r.1 */
=> EPART SPACE EPART /* r.2 */
=> EPART /* r.4 */
== "m<o>tley crueが好き"
=> iso-8859-1 "m<o>tley crue" /* charsetで分割 */
iso-2022-jp "が好き"
=> "=?iso-8859-1?Q?m=F6tley_crue?= =?iso-2022-jp?B?GyRCJCw5JSQtGyhC?="
or
=> iso-2022-jp-2 "m<o>tley cureが好き" /* 包含charset */
=> "=?iso-2022-jp-2?B?bRsuQRtOdnRsZXkgY3J1ZRskQiQsOSUkLRsoQg==?="
(3) m<o>tley crue "が好き"
"m<o>tley crue \"が好き\""
=> "m<o>tley" " " "crue" " " "\"が好き\""
== EWORD SPACE AWORD SPACE EWORD
=> EPART AWORD EWORD /* r.1 */
=> EPART AWORD EPART /* r.1 */
=> EPART APART EPART /* r.8 */
== "m<o>tley" " crue " "\"が好き\""
=> iso-8859-1 "m<o>tley"
ascii " crue "
iso-2022-jp "\"が好き\""
=> "=?iso-8859-1?Q?m=F6tley?= crue =?iso-2022-jp?B?IhskQiQsOSUkLRsoQiI=?="
(4) m<o>tley crue"が好き"
"m<o>tley crue\"が好き\""
=> "m<o>tley" " " "crue\"が好き\""
== EWORD SPACE EWORD
=> EPART SPACE EWORD /* r.1 */
=> EPART SPACE EPART /* r.1 */
=> EPART /* r.4 */
== "m<o>tley crue\"が好き\""
=> iso-8859-1 "m<o>tley crue\"" /* charsetで分割 */
iso-2022-jp "が好き\""
=> "=?iso-8859-1?Q?m=F6tley_crue"?= =?iso-2022-jp?B?GyRCJCw5JSQtGyhCIg==?="
or
=> iso-2022-jp-2 "m<o>tley crue\"が好き\"" /* 包含charset */
=> "=?iso-2022-jp-2?B?bRsuQRtOdnRsZXkgY3J1ZSIbJEIkLDklJC0bKEIi?="
(5) m<o>tley "crue が好き"
"m<o>tley \"crue が好き\""
=> "m<o>tley" " " "\"crue" " " "が好き\""
== EWORD SPACE AWORD SPACE EWORD
=> EPART SPACE AWORD SPACE EWORD /* r.1 */
=> EPART SPACE AWORD SPACE EPART /* r.1 */
=> EPART APART EPART /* r.8 */
== "m<o>tley" " \"crue " "が好き\""
=> iso-8859-1 "m<o>tley"
ascii " \"crue "
iso-2022-jp "が好き\""
=> "=?iso-8859-1?Q?m=F6tley?= \"crue =?iso-2022-jp?B?GyRCJCw5JSQtGyhCIg==?="
-------------- next part --------------
kazu> (問3) 問2 で答えたアルゴリズムが、いかなるパターンでも最適解を選択/生
kazu> 成することの正当性を証明せよ。[30点]
#証明はパス
text部でRFC-2047を実践するに当たっての注意点はエンコードを行う部分
(encoded-word)とそうでない部分とに分ける方法である。このとき空白文字
(列)の保存の問題があり、以下のルールに注意する
1. encoded-wordとascii文字列の間には空白が必要
2. encoded-word 同士間の空白は保存されない。
問2のアルゴリズムにおいて、APARTは両端に常に空白、あるいはBOL,EOLを
維持する。またEPARTとAWORDの間に空白がない場合は上記1の問題を回避する
ために単一のEPARTとする。
これによりAPARTに隣接するEWORDのエンコードにおける上記1の問題はクリア
される。
-------------- next part --------------
kazu> (問3) 問1、問2 の答えを元に Subject: を符号化するアルゴリズムを Elisp
kazu> で記述せよ。ただし、Mew がサポートしている Emacs/XEmacs/Mule で問題な
kazu> く動く必要がある。さらに、プログラムは 1 パスで終了しなければならない。
kazu> [40点]
ちょっと長いですがこんなのでどうでしょうか。
#関数の命名はテキトーです。
#foldingはとりあえず考慮していません。
#string から stringを生成します。
最初mew-1.93b37環境で作り、後になってmew-1.93b48で動作するように
修正しましたので、ちょいと冗長なところもありますが御愛嬌。
mew-1.93b48がロードされている状態で添付したコードをロードし、
(rfc2047-encode ".....") を評価してください。
#先の回答はこの結果によるものです。
また、「1パス」意味が不明瞭なのでその辺はパス :-)
;; -*- Emacs-Lisp -*-
;;
;; my-mew-enc.el -- no desc
;; $Revision$
;; Author: Shun-ichi GOTO <gotoh at example.com>
;; Create: Sat Jul 18 20:51:31 1998
;;; Commentary:
;;
;;; Code:
;; sample: (See [Mew-dist 05595] Re: b47)
;; m<o>tley crue が好き
;; => "=?iso-8859-1?Q?m=F6tley?= crue =?iso-2022-jp?B?GyRCJCw5JSQtGyhC?="
;; m<o>tley crueが好き
;; => "=?iso-2022-jp-2?B?bRsuQRtOdnRsZXkgY3J1ZRskQiQsOSUkLRsoQg==?="
;; m<o>tley crue "が好き"
;; => "=?iso-8859-1?Q?m=F6tley?= crue =?iso-2022-jp?B?IhskQiQsOSUkLRsoQiI=?="
;; m<o>tley crue"が好き"
;; => "=?iso-2022-jp-2?B?bRsuQRtOdnRsZXkgY3J1ZSIbJEIkLDklJC0bKEIi?="
;; m<o>tley "crue が好き"
;; => "=?iso-8859-1?Q?m=F6tley?= \"crue =?iso-2022-jp?B?GyRCJCw5JSQtGyhCIg==?="
(defconst rfc2047-text-ascii-regexp
"\\(\\(^\\|[ \t]+\\)[\040-\177][ \t\040-\177]*\\([ \t]+\\|$\\)\\)")
(defvar rfc2047-encode-as-minimum-charset nil
"If this value is t, word which contains both iso-2022-jp and
iso-8859-1 is encoded not single encoded-word of iso-2022-jp-2
but two encoded-word of iso-2022-jp and iso-8859-1")
(defun mew-rfc2047-text-split (str)
(let ((slist nil)
estr astr
ebeg eend
abeg aend)
;; "eeee aaaa ... " => ("eee" "aaaa") and "...."
(while (< 0 (length str))
(if (string-match rfc2047-text-ascii-regexp str)
;; found cut out
(setq slist (cons (cons (substring str 0 (match-beginning 1))
(substring str
(match-beginning 1)
(match-end 1)))
slist)
str (substring str (match-end 1))) ; update
;; not found ... all for encoded
(setq slist (cons (cons str "") slist)
str "") ;; no more
))
(nreverse slist)))
(defun mew-find-charset-info (tcsl)
"Give list of coding system symbols, return encode information if acceptable"
(let ((alst mew-cs-database)
(N (length tcsl))
tmpl a acsl aret acs aenc csl ret)
(setq tcsl (delq 'ascii tcsl))
(while (and (null ret) alst)
(setq a (car alst))
(setq acsl (nth 1 a))
(setq aret (nth 0 a))
(setq acs (nth 4 a))
(setq aenc (nth 5 a))
(setq alst (cdr alst))
(catch 'loop
(setq tmpl tcsl)
(while tmpl
(if (mew-member (car tmpl) acsl)
()
(setq aret nil)
(setq acsl nil)
(throw 'loop nil))
(setq tmpl (cdr tmpl)))
;; all in single charset
(setq ret (list aret acs aenc ))))
ret))
(defun mew-split-string-by-charset (str)
"Separete given STR by coding system.
ascii only or ascii and other one may be included for each list of result.
"
(let ((sub "")
(pos 0)
(len (length str))
(wlist nil) ; result
charset cs ch csl beg info cst)
(while (< pos len)
(setq cat nil
beg pos
csl (list 'ascii) ; accepted coding system except ascii
charset nil) ; result charset
(while (and (< pos len)
(progn
(setq ch (mew-aref str pos)
cs (char-charset ch))
(if (memq cs csl)
t ; already accepted coding-system
;; check this cs is allowable as single charset
(setq cst (mew-find-charset-info (cons cs csl)))
(if (null cst)
nil ; deny
(if (and rfc2047-encode-as-minimum-charset
charset
(not (string= charset (car cst))))
nil ; deny
(setq csl (cons cs csl)
charset (car cst))))
)))
;; accepted
(setq pos (+ pos (mew-charlen ch))))
(setq info (mew-find-charset-info csl))
(setq wlist (cons (list (nth 0 info)
(nth 2 info)
(substring str beg pos)
(nth 1 info))
wlist)))
(nreverse wlist)))
(defun rfc2047-encode (str)
""
(let ((slist (mew-rfc2047-text-split str))
(result "")
elist estr astr)
(while slist
(setq estr (car (car slist))
astr (cdr (car slist)))
;; string to be encode
(if (or (null estr)
(= 0 (length estr)))
()
(setq result
(concat result
(mapconcat
'(lambda (x)
(let* ((charset (nth 0 x))
(bq (nth 1 x))
(str (nth 2 x))
(cs (nth 3 x))
(func (cdr (mew-assoc-case-equal
bq mew-header-encode-switch 0))))
(concat "=?" charset "?" bq "?"
(funcall func str) "?=")))
(mew-split-string-by-charset estr) " "))))
;; string to be as-is (ASCII)
(if (and astr
(< 0 (length astr)))
(setq result (concat result astr)))
(setq slist (cdr slist)))
result))
;; my-mew-enc.el ends here
-------------- next part --------------
添付メールを保管しました...
送信者: Shun-ichi GOTO <gotoh at example.com>
件名: #1 =?iso-8859-1?Q?m=F6tley?= crue =?iso-2022-jp?B?GyRCJCw5JSQtGyhC?=
日付: Sun, 19 Jul 1998 02:06:55 +0900
サイズ: 815 バイト
URL: <http://www.mew.org/pipermail/mew-dist/attachments/19980719/46d497c9/attachment.mht>
Mew-dist メーリングリストの案内