.NET Frameworkにおけるテキストのエンコード・デコード、エスケープ・アンエスケープ、フォーマット変換、暗号化などについて。
文字コード
文字コードを指定して文字列をバイト配列にエンコードしたり、逆にデコードしたりする場合にはSystem.Text.Encodingクラスを使います。
バイト配列を別の文字コードでの表現に変換するにはEncoding.Convertメソッドを使います。
文字コードを指定したファイルの読み書きについてはStreamReaderクラス・StreamWriterクラスで解説しています。 その他、文字コードとEncodingクラスについては以下のページでも解説しています。
- ファイル入出力 §.文字コード
- EncodingクラスとBOMありなしの制御 .NET FrameworkにおけるBOMの扱いについて
- Shift JISとEUC-JPの判別 文字コードを検出する例
- 文字・文字列のバイト数を調べる
- Modified UTF-7のエンコード・デコード
Base64
バイト配列をBase64に変換するにはSystem.ConvertクラスのToBase64Stringメソッド・FromBase64Stringメソッドを使います。 文字列とBase64形式の文字列を直接相互に変換することは出来ないので、その場合にはまず文字列をバイト配列に変換してからこれらのメソッドを呼び出す必要があります。
ToBase64Stringメソッドでは、引数にBase64FormattingOptions.InsertLineBreaksを指定すると、Base64への変換に際して76文字ごとに改行を入れるようにすることができます。 Base64でメールの本文をエンコードする場合などに使用することができます。
ストリームをBase64で変換したり、Base64形式でファイルの読み書きをする場合には、System.Security.Cryptography名前空間のCryptoStreamとToBase64Transform・FromBase64Transformを組み合わせて使います。
次のコードは、Base64・UTF-8でエンコードしてファイルを読み書きする例です。
このコードでは、次のようにしてBase64・UTF-8への変換が行われます。
ストリームを多段に重ねて使う方法についてはストリームの基本とStreamクラス §.データフォーマットの変換やバッファリングなどの機能を追加するStream派生クラス、StreamWriter・StreamReaderについてはStreamReaderクラス・StreamWriterクラスで詳しく解説しています。
quoted-printable
.NET Frameworkにはquoted-printableのエンコード・デコードを行うクラスやメソッドは用意されていません。 必要な場合は独自に実装する必要があります。
MIMEエンコード (Qエンコード・Bエンコード)
.NET FrameworkにはMIMEエンコード・デコードを行うクラスやメソッドは用意されていません。 必要な場合はBASE64の変換・quoted-printableの変換・文字コードの変換を組み合わせて独自に実装する必要があります。
URLエンコード・パーセントエンコード
エンコード
URLエンコード(パーセントエンコード)を行うメソッドには次の4つを使うことができます。 それぞれの違いは次のとおりです。
メソッド | 動作と適用範囲 | 文字コード | 必要アセンブリ・バージョン |
---|---|---|---|
System.Uri.EscapeUriString |
/
#
&
=
? などURIで特別な意味を持つ記号は変換されない(URIとして使用する文字列を変換する際にはこのメソッドを使用する) |
常にUTF-8でエンコードされる | System.dll (.NET Framework 1.0以降) |
System.Uri.EscapeDataString |
/
#
&
=
? などの記号も変換される(URIのクエリ部分などに使用する文字列を変換する際にはこのメソッドを使用する) |
System.dll (.NET Framework 1.0以降) |
|
System.Net.WebUtility.UrlEncode | System.dll (.NET Framework 4.5以降) |
||
System.Web.HttpUtility.UrlEncode | 任意のEncodingを指定してエンコードできる | System.Web.dll (.NET Framework 1.1以降) |
これらのメソッドの変換結果には細かな違いがあり、変換される記号の違いのほか、空白(0x20)を%20
に変換するか+
に変換するか、大文字小文字どちらにエンコードされるか、といった違いがあります。
さらにUri.EscapeUriString・Uri.EscapeDataStringについては、.NET Framework 4.0まではRFC 2396に基づいて変換を行いますが、.NET Framework 4.5以降ではRFC 3986に基づいて変換されるように動作が変更されているという点にも注意が必要です。
0x20から0x7fまでの文字と各メソッドの変換結果の違いを表にすると次のようになります。
! | " | # | $ | % | & | ' | ( | ) | * | + | , | - | . | / | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | < | = | > | ? | ||
Uri.EscapeUriString (.NET 4.5以降) | %20 | ! | %22 | # | $ | %25 | & | ' | ( | ) | * | + | , | - | . | / | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | %3C | = | %3E | ? |
Uri.EscapeUriString (.NET 4.0まで) | %20 | ! | %22 | # | $ | %25 | & | ' | ( | ) | * | + | , | - | . | / | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | : | ; | %3C | = | %3E | ? |
Uri.EscapeDataString (.NET 4.5以降) | %20 | %21 | %22 | %23 | %24 | %25 | %26 | %27 | %28 | %29 | %2A | %2B | %2C | - | . | %2F | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | %3A | %3B | %3C | %3D | %3E | %3F |
Uri.EscapeDataString (.NET 4.0まで) | %20 | ! | %22 | %23 | %24 | %25 | %26 | ' | ( | ) | * | %2B | %2C | - | . | %2F | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | %3A | %3B | %3C | %3D | %3E | %3F |
WebUtility.UrlEncode | + | ! | %22 | %23 | %24 | %25 | %26 | %27 | ( | ) | * | %2B | %2C | - | . | %2F | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | %3A | %3B | %3C | %3D | %3E | %3F |
HttpUtility.UrlEncode | + | ! | %22 | %23 | %24 | %25 | %26 | %27 | ( | ) | * | %2b | %2c | - | . | %2f | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | %3a | %3b | %3c | %3d | %3e | %3f |
@ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | [ | \ | ] | ^ | _ | |
Uri.EscapeUriString (.NET 4.5以降) | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | [ | %5C | ] | %5E | _ |
Uri.EscapeUriString (.NET 4.0まで) | @ | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | %5B | %5C | %5D | %5E | _ |
Uri.EscapeDataString (.NET 4.5以降) | %40 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | %5B | %5C | %5D | %5E | _ |
Uri.EscapeDataString (.NET 4.0まで) | %40 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | %5B | %5C | %5D | %5E | _ |
WebUtility.UrlEncode | %40 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | %5B | %5C | %5D | %5E | _ |
HttpUtility.UrlEncode | %40 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | %5b | %5c | %5d | %5e | _ |
` | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | { | | | } | ~ | | |
Uri.EscapeUriString (.NET 4.5以降) | %60 | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | %7B | %7C | %7D | ~ | %7F |
Uri.EscapeUriString (.NET 4.0まで) | %60 | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | %7B | %7C | %7D | ~ | %7F |
Uri.EscapeDataString (.NET 4.5以降) | %60 | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | %7B | %7C | %7D | ~ | %7F |
Uri.EscapeDataString (.NET 4.0まで) | %60 | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | %7B | %7C | %7D | ~ | %7F |
WebUtility.UrlEncode | %60 | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | %7B | %7C | %7D | %7E | %7F |
HttpUtility.UrlEncode | %60 | a | b | c | d | e | f | g | h | i | j | k | l | m | n | o | p | q | r | s | t | u | v | w | x | y | z | %7b | %7c | %7d | %7e | %7f |
デコード
URLエンコード(パーセントエンコード)された文字列のデコードを行うには次の3つのメソッドを使うことができます。 それぞれの違いは次のとおりです。
メソッド | 動作 | 文字コード | 必要アセンブリ・バージョン |
---|---|---|---|
System.Uri.UnescapeDataString | 文字列中の+ はそのままデコードされる |
常にUTF-8でデコードされる | System.dll (.NET Framework 1.0以降) |
System.Net.WebUtility.UrlDecode | 文字列中の+ はデコード時に空白に変換される |
System.dll (.NET Framework 4.5以降) |
|
System.Web.HttpUtility.UrlDecode | 任意のEncodingを指定してデコードできる | System.Web.dll (.NET Framework 1.1以降) |
デコードする文字列と+
の扱いについてはURLのデコード・アンエスケープ(HttpUtility.UrlDecode、Uri.UnescapeDataString)でも解説しています。
HTMLエンコード・エンティティ化
.NET Framework 4.5以降では、System.Net.WebUtilityクラスのHtmlEncode・HtmlDecodeメソッドを使うことでHTMLエンコードを行うことができます。 HtmlEncodeメソッドでは、"
&
<
>
に加えて'
の計5つの記号がエンコードされます。 HtmlDecodeメソッドでは、'
"
&
<
>
がデコードされるほか、10進・16進の数値文字参照(エンティティ)もデコードされます。
4.5より前の.NET FrameworkやASP.NETでは、System.Web.dllにあるSystem.Web.HttpUtilityクラスのHtmlEncode・HtmlDecodeメソッドを使うことで同様のことを行えます。
一部の記号だけでなくすべての文字を数値文字参照に変換(エンティティ化)するメソッドは用意されていないので、次の例のように独自に実装する必要があります。
日付と時刻
DateTime.ToStringメソッドの引数に書式を指定することにより、日時をよく使われる形式の文字列へと変換することができます。 書式指定子"r"
を指定するとRFC1123形式、"o"
を指定するとISO8601(W3C-DTF)形式の文字列に変換できます。
また逆に、ParseExactメソッドを使うことによりこれらの形式で表記された文字列をDateTime・DateTimeOffsetに変換することができます。
DateTime構造体・DateTimeOffset構造体については日付・時刻の型と操作、日時と書式については日時・文字列の変換と書式や書式指定子で詳しく解説しています。
ハッシュ化
MD5, SHA-1, SHA-512などのハッシュ関数を使ってハッシュ値を求めるには、System.Security.Cryptography名前空間のMD5クラス・SHA1クラス・SHA512クラスなどのHashAlgorithmクラスから派生したクラスを使うことができます。
これらのクラスでは、ComputeHashメソッドにバイト配列を指定すると、そのバイト配列のハッシュ値を取得することができます。 文字列から直接ハッシュ値を求めることはできないので、先に文字列をバイト配列に変換する必要があります。
以下の例ではMD5クラスを使用していますが、SHA1クラス・SHA512クラスに置き換えればSHA-1, SHA-512のハッシュ値を求めることができます。
Computeハッシュメソッドは引数にStreamクラスを指定することもできます。 ファイルのハッシュ値を求める場合は次のようにします。
ハッシュ値を求める例については以下のページでも紹介しています。
暗号化・復号化
System.Security.Cryptography名前空間にあるクラスを使うことで暗号化・復号化を行うことができます。 次の例では、共通鍵方式のTriple DES(3DES)での暗号化・復号化を行うTripleDESクラスを使い、暗号化してファイルに文字列を書き込んだあと、再度ファイルを読み込んで復号化しています。
上記の例では初期化ベクタ(IV)とキー(Key)の生成を省略しています。 初期ベクタとキーの生成・送受信には安全な方法をとるようにしてください。
ストリームを多段に重ねて使う方法についてはストリームの基本とStreamクラス §.データフォーマットの変換やバッファリングなどの機能を追加するStream派生クラス、StreamWriter・StreamReaderについてはStreamReaderクラス・StreamWriterクラスで詳しく解説しています。
圧縮・伸長
System.IO.Compression名前空間にあるクラスを使うことで圧縮・展開を行うことができます。 gzip形式での圧縮・伸長にはGZipStreamクラス、LZ77形式での圧縮・伸長にはDeflateStreamクラスを使うことができます。
これらのクラスについてはSystem.IO.Compression.GZipStreamで詳しく解説しています。