From: Akinori MUSHA Date: 2006-10-14T18:44:15+09:00 Subject: [ruby-dev:29661] Re: Digest'ifying OpenSSL::Digest At Sat, 14 Oct 2006 11:34:50 +0900, GOTOU Yuuzou wrote: > >  メリットとしては、苦もなくAPIが統一される、 #file() などの追加 > > メソッドが使える、 bubblebabble や hmac (OpenSSL にもあるが)等の > > アドインの恩恵を受けられる、などです。 > > 目的には賛成します。 > > 最近のext/digestの変更を追っかけていませんでしたが、内部の実 > 装に関わらない機能であれば、例えば::Digest::Utilitiesみたい > なモジュールを用意して、 > > class OpenSSL::Digest::Digest > class < include ::Digest::Utilities::SingletonMethods > end > include ::Digest::Utilities::InstanceMethods > end > > こんな風にできると楽かなとも思いました。  確かに mix-in にした方が美しいですね。検討します。  今いろいろ悩んでいるのは、キーやハッシュ長などのパラメータを 取るアルゴリズムをどう扱うかです。  たとえば、あるメソッドがハッシュアルゴリズムの指定を受けると したときを考えます。  まず、 check_auth(cookie, "MD5") と名称を文字列で渡す方法では、パラメータの指定が困難です。 check_auth(cookie, "HMAC;hash=MD5;key=blahblahblah") と DBI みたいな感じにしたのでは、指定もパースも面倒なので論外。  また、 check_auth(cookie, Digest::MD5) のようにクラスオブジェクトを渡す方法がありますが、パラメータ付き アルゴリズムの場合、パラメータ(の組合せ)ごとに固有のクラスを作る のかというと躊躇します。(digest/hmac で一度やってみました)  かといって、 check_auth(cookie, Digest::Tiger, 160) のようにパラメータを並べて渡すのでは「計算器」をひとまとまりで 指定できていないので美しくない。  計算器を渡す、という意味では check_auth(cookie, Digest::Tiger.new(160)) というのがひとつの解決策であり、現時点の digest はこのような形を 想定していますが、いくつか問題もあります。 ・同時に複数の計算器インスタンスを必要とする場合、 clone() して もらうのか? ・状態のあるものをやりとりするのは気持ち悪い。使用前・使用後に reset() する責任の有無などが気になる。  つまり、渡すべきなのは計算器そのものではなくて、計算器の生成 方法であるということになります。  ということは、先ほどのクラスオブジェクトを渡す方法がいちばん 近そうです。あるべき姿は ・Digest 実装クラスは new() でパラメータを受け取り、 factory オブジェクトを生成する。 ・factory オブジェクトは自身の生成時に指定されたアルゴリズムと パラメータに沿った「計算器」を生成する能力(メソッド)を持つ。 といった形でしょうか。でも、まじめにそうしてしまうとあんまり 使いやすい感じはしないですね。 tiger160 = Digest::Tiger.new(160) hash = tiger160.create() hash.update(data) digest = hash.digest JCE の Mac クラスなどはこんな感じのインターフェースですが、 果たして Ruby にマッチするのかどうか。  ショートカットメソッドをいろいろ作れば短く書く方法を提供できる でしょうが、冗長で構造がつかみにくいものになってしまいそうです。  そもそもの話としてすべてのハッシュ関数のインターフェースを統一 する必要があるのかという疑問は考えられます。MD5 または HMAC-MD5、 などという選択が実際あるのかどうか分かりませんし。  ただ、現実を予測するのは難しいので、もう少し理想について考えて みたいです。等しく難しいのなら。 > 名前が見苦しいのはまったく同感です。現在の > OpenSSL::Digest::DigestクラスをOpenSSL::Digestという名前にし > て、OpenSSL::Digest.new(name)にしようかと考えてはいました。 > > # ほかにもOpenSSL::PKey::PKeyなんかもあるので、1.9ではまとめ > # て変更することを検討します。  ぜひいい形にしたいですね。 > 名前はさておき、[ruby-dev:29651]のパッチではアルゴリズム毎に > サブクラスを作成し、サブクラス毎に個別にメソッドを定義してい > るのが受け入れがたいです。 > > OpenSSL::Digest::DigestはOpenSSLライブラリに定義されている任 > 意のアルゴリズム名で初期化できるようになっています。例えば、  なるほど。あくまで動的な名前指定が主で、個別クラスは従ですか。 念頭においていじってみます。 -- / /__ __ Akinori.org / MUSHA.org / ) ) ) ) / FreeBSD.org / Ruby-lang.org Akinori MUSHA aka / (_ / ( (__( @ iDaemons.org / and.or.jp "Different eyes see different things, Different hearts beat on different strings -- But there are times for you and me when all such things agree"