C#と諸々

C#がメインで他もまぁ諸々なブログです
おかしなこと書いてたら指摘してくれると嬉しいです(´・∀・`)
つーかコメント欲しい(´・ω・`)

2006/10/04 19:37
以前、コーディング俺規約 - フィールドの初期化という記事で、フィールドの初期化はコンストラクタで行った方がいいと書きました。そして、 「静的フィールドも同様に静的コンストラクタで初期化する。」 と書きました。が、静的フィールドの初期化に関しては、静的コンストラクタで行うのは不適切なようでした。理由は、以下に記述。


静的コンストラクタはインスタンスコンストラクタと違い、コンパイル時に特殊な処理が行われる。

静的コンストラクタを明示的に宣言しない場合、コンパイラが静的コンストラクタを用意してくれる。しかし、それだけではなく、beforefieldinitというフラグがそのクラスのMSIL定義に追加される。
静的コンストラクタを明示的に宣言した場合は、beforefieldinit フラグは追加されない。

beforefieldinit フラグがない(明示的に静的コンストラクタを宣言した)場合、その型の静的フィールドに初めてアクセスしようとした時、静的コンストラクタが実行される。また、静的コンストラクタが実行されたかどうかを確認するためのチェックが加えられる。

beforefieldinit フラグがある(明示的に静的コンストラクタを宣言しない)場合、その型の静的フィールドに初めてアクセスするよりも前に、静的コンストラクタが実行されることが保証される。beforefieldinitフラグがあると、ほとんどの場合、静的コンストラクタが実行されたかどうかを確認するチェックは加えられない。

静的コンストラクタが実行されたかどうかのチェックが加えられると、パフォーマンスが低下する場合があるらしい。
よって、静的フィールドの初期化は宣言時に行い、静的コンストラクタは明示的に宣言しないようにするのが適切である。


[ 検証 ]
以下のような検証用プログラムを組んでみた。

検証用プログラムclass Program
{
    static void Main(string[] args)
    {
        double time1 = Hoge.InitTime.Subtract(DateTime.Now).TotalSeconds;
        double time2 = Foo.InitTime.Subtract(DateTime.Now).TotalSeconds;
        Console.WriteLine("beforefieldinitフラグありの場合の初期化:{0}", time1);
        Console.WriteLine("beforefieldinitフラグなしの場合の初期化:{0}", time2);
        Console.ReadLine();
    }

    static class Hoge
    {
        public static DateTime InitTime = DateTime.Now;
    }

    static class Foo
    {
        public static DateTime InitTime;

        static Foo()
        {
            Foo.InitTime = DateTime.Now;
        }
    }
}


検証用プログラムをコンパイルすると、HogeクラスとFooクラスのMSILコードは、以下のようになる。Hogeクラスのクラス宣言部にはbeforefieldinit フラグがあり、Fooクラスのクラス宣言部にはbeforefieldinit フラグがないことが確認できる。

HogeクラスのMSILコード.class nested private abstract auto ansi sealed beforefieldinit Hoge
    extends object
{
    .method private hidebysig specialname rtspecialname static void .cctor() cil managed
    {
        .maxstack 8
        L_0000: call [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()
        L_0005: stsfld [mscorlib]System.DateTime ConsoleApplication1.Program/Hoge::InitTime
        L_000a: ret
    }

    .field public static [mscorlib]System.DateTime InitTime
}

FooクラスのMSILコード.class nested private abstract auto ansi sealed Foo
    extends object
{
    .method private hidebysig specialname rtspecialname static void .cctor() cil managed
    {
        .maxstack 8
        L_0000: nop
        L_0001: call [mscorlib]System.DateTime [mscorlib]System.DateTime::get_Now()
        L_0006: stsfld [mscorlib]System.DateTime ConsoleApplication1.Program/Foo::InitTime
        L_000b: ret
    }

    .field public static [mscorlib]System.DateTime InitTime
}


検証用プログラムを実行すると、以下のような出力を得られる。

実行結果
beforefieldinitフラグありの場合の初期化:-0.03125
beforefieldinitフラグなしの場合の初期化:0


この結果から、beforefieldinitフラグありの場合、静的フィールドにアクセスするよりも前に、静的フィールドの初期化が行われていることがわかる。


[ 参照 ]
値型の静的フィールドをインラインで初期化します
参照型の静的フィールドをインラインで初期化します


スポンサーサイト



タグ: .NET C#
2006/10/04 03:53
電子署名とは、電子的なデータやファイルの正当性を保証するための技術である。
電子署名にはいくつか種類があるが、RSA暗号化方式を用いた電子書名が特に有名である。
この記事では、RSA暗号化方式について解説する。

[ RSA暗号化方式 ]
公開鍵基盤(PKI)のひとつ。
秘密鍵と公開鍵という2種類の鍵と、電子証明書から成る。
RSA以外にもDSA等の方式があるが、RSAと他の方式では、秘密鍵と公開鍵の性質や署名の生成方法等が異なるので注意。


[ 電子証明書 ]
電子的な身分証明書。信頼できる第三者(認証局)に発行してもらう。
電子証明書には、認証局の電子証明書によって電子署名が施される。これにより、信頼できる第三者が発行したことが証明される。
認証局に発行してもらった電子証明書には秘密鍵と公開鍵が含まれている。また、他者に公開するためには、公開鍵のみを含んだ電子証明書を公開する。

実は、電子署名の発行は専用のツール(無償で入手可能)さえあれば誰にでもできる。自分自身の電子証明書を作ることも可能で、これは一般に「オレオレ証明書」と呼ばれていて、通常、この証明書には信頼性が全くない。

日本では、2001年4月1日から電子署名法が施行された。これにより、認定を受けた認証業務 (総務大臣,経済産業大臣,法務大臣の認定を受けた電子証明書発行サービス) で発行してもらった電子証明書による電子署名は、法的な効力を持つ。(発行は有償。また、電子証明書には有効期限がある。)
電子証明書はいくつも種類があり、どれを(どの認証局で)購入すればいいかは利用目的により異なる。


[ 秘密鍵と公開鍵 ]
秘密鍵は本人以外の手に渡ってはいけないもので、本人が厳重に保管する必要がある。
公開鍵は本人以外に公開してよいものである。
秘密鍵と公開鍵は暗号化・復号化を行うためのものである。
秘密鍵と公開鍵は対になっていて、秘密鍵で暗号化したデータは公開鍵でのみ復号化でき、公開鍵で暗号化したデータは秘密鍵でのみ復号化できる。


[ 電子署名 ]
データに対する電子的な署名。
電子署名は、対象のデータのハッシュ値を秘密鍵で暗号化したものである。
電子証明を公開鍵によって復号化した値と、対象データのハッシュ値を比較することで、 データ改竄の有無を調べることができる。

exeファイルやdllファイル、pdfファイル等では、電子署名をファイルに埋め込むことができる。
だが、jpegファイルなどではファイルに埋め込むことができないので、電子署名は独立した一つのファイルとなる。

電子署名は、データの正当性と署名を行った人物を証明する。しかし、署名を行った日時を証明することはできない。日時の証明には「タイムスタンプ」という技術 を利用する。 (タイムスタンプも電子署名を利用した技術である。簡単に説明すると、対象のデータのハッシュ値に国際原子時を加えたものに電子署名を行ったものがタイムスタンプとなる。)