C#で数値を扱う際、デバッグ情報の表示や通信プロトコルの解析などで、数値を16進数形式の文字列に変換したい場面が多々あります。
C#には、数値を直感的に16進数へ変換するための強力なメソッドが標準で備わっています。
本記事では、ToStringメソッドを利用した基本的な変換方法から、書式指定による桁数の制御、さらには最新の.NET環境における効率的な変換手法まで詳しく解説します。
開発現場ですぐに活用できる具体的なコード例を交えながら、16進数変換の知識を整理していきましょう。
ToStringメソッドによる16進数変換の基本
C#の数値型(int, long, byteなど)には、文字列へ変換するためのToStringメソッドが用意されています。
このメソッドの引数に特定の書式指定子を渡すことで、数値を簡単に16進数文字列として出力できます。
「X」と「x」による大文字・小文字の使い分け
16進数変換において最も重要な書式指定子は、「X」または「x」です。
大文字の「X」を指定すると、変換後のアルファベット(A~F)が大文字で出力されます。
一方で、小文字の「x」を指定すると、アルファベット(a~f)は小文字で出力されるようになります。
int value = 255;
// 大文字の16進数に変換
string upperHex = value.ToString("X");
// 小文字の16進数に変換
string lowerHex = value.ToString("x");
Console.WriteLine($"Upper: {upperHex}");
Console.WriteLine($"Lower: {lowerHex}");
Upper: FF
Lower: ff
桁数の指定とゼロ埋め(パディング)
特定の桁数で16進数を出力したい場合は、書式指定子の後ろに数値を記述します。
例えば、「X2」と指定すると、数値が1桁であっても2桁になるように「0」で埋められます。 これは、バイトデータを扱う際や、カラーコードを生成する際に非常に便利な機能です。
int value = 10;
// 2桁で出力(0Aとなる)
string hex2 = value.ToString("X2");
// 4桁で出力(000Aとなる)
string hex4 = value.ToString("X4");
Console.WriteLine($"Hex2: {hex2}");
Console.WriteLine($"Hex4: {hex4}");
Hex2: 0A
Hex4: 000A
文字列補完(String Interpolation)での16進数表示
現代的なC#のコーディングでは、ToStringメソッドを直接呼び出す代わりに、文字列補完式を使用することが推奨されます。
文字列補完の中でも、変数名の後ろにコロンを付けることで、ToStringと同じ書式指定子を適用できます。
コードの可読性を高めるために、積極的にこの記述方法を活用しましょう。
int val = 1024;
// 文字列補完を利用した16進数表示
string message = $"値の16進数表記は 0x{val:X4} です。";
Console.WriteLine(message);
値の16進数表記は 0x0400 です。
バイト配列を効率的に16進数文字列へ変換する
通信処理や暗号化処理では、単一の数値ではなく、byte[](バイト配列)全体を16進数文字列に変換したいケースがあります。
以前のC#ではBitConverterやStringBuilderを組み合わせて実装していましたが、現在の.NETではより効率的な方法が存在します。
Convert.ToHexStringメソッドの利用
.NET 5以降では、Convert.ToHexStringメソッドを使用するのが最も標準的で高速な方法です。
このメソッドは、バイト配列をハイフンなしの大文字16進数文字列へ一括変換します。
byte[] data = { 0, 15, 255, 128 };
// バイト配列を16進数文字列に変換
string hexString = Convert.ToHexString(data);
Console.WriteLine(hexString);
000FFF80
BitConverterクラスによる変換
古いフレームワークとの互換性を保つ必要がある場合は、BitConverter.ToStringメソッドが利用されます。
このメソッドで変換すると、各バイトがハイフンで区切られた形式で出力されます。
ハイフンが不要な場合は、Replace("-", "")メソッドを呼び出して除去する必要があります。
byte[] data = { 0, 15, 255, 128 };
// ハイフン区切りの文字列が生成される
string bitString = BitConverter.ToString(data);
Console.WriteLine(bitString);
00-0F-FF-80
16進数文字列から数値への逆変換
16進数文字列を表示するだけでなく、入力された16進数文字列を数値型に戻す処理も重要です。
これには、int.ParseやConvert.ToInt32などのメソッドを使用します。
int.Parseによる変換
int.Parseメソッドを使用する場合、第二引数にSystem.Globalization.NumberStyles.HexNumberを指定する必要があります。
「0x」というプレフィックスが含まれている場合は、解析に失敗するため、事前除去が必要です。
string hexInput = "FF";
// 16進数として解析
int result = int.Parse(hexInput, System.Globalization.NumberStyles.HexNumber);
Console.WriteLine($"変換結果: {result}");
変換結果: 255
Convert.ToInt32による変換
Convert.ToInt32メソッドを使用する場合、第二引数に基数として「16」を指定します。
このメソッドの利点は、文字列が「0x」から始まっていても正しく解釈できる点にあります。
string hexWithPrefix = "0x100";
// 基数16を指定して変換
int val = Convert.ToInt32(hexWithPrefix, 16);
Console.WriteLine($"変換結果: {val}");
変換結果: 256
パフォーマンスを意識した16進数変換
高頻度で変換処理を行うアプリケーション(例:大容量ファイルのバイナリエディタなど)では、文字列の生成コストが無視できません。
最新のC#では、メモリ割り当て(アロケーション)を抑えるための手法が提供されています。
Span構造体とTryFormatの活用
Span<char>を使用することで、ヒープメモリに新しい文字列を作成せずに、既存のバッファへ直接16進数を書き込むことができます。
数値型のTryFormatメソッドを使用すると、指定したバッファ内に直接書き込みを行うことが可能です。
int value = 12345;
Span<char> buffer = stackalloc char[8];
// スタック領域のバッファへ直接書き込み
if (value.TryFormat(buffer, out int charsWritten, "X"))
{
Console.WriteLine($"書き込まれた内容: {buffer.Slice(0, charsWritten).ToString()}");
}
書き込まれた内容: 3039
ISpanFormattableインターフェース
多くの数値型は、最新の.NETにおいてISpanFormattableインターフェースを実装しています。
これにより、ジェネリックなメソッド内でも効率的に16進数フォーマットを扱うことができます。
パフォーマンスが要求されるライブラリ開発では、これらのSpanベースのAPIを選択することが推奨されます。
実戦で役立つ16進数変換の応用例
16進数変換は、単なる数値の表示以外にも多くの実用的な場面で利用されます。
代表的な2つのケースを紹介します。
カラーコードの生成
GUIアプリケーションで、RGB値を16進数のカラーコード(#RRGGBB形式)に変換する例です。
各色コンポーネントを「X2」でフォーマットすることで、常に2桁の16進数を得ることができます。
int r = 255, g = 165, b = 0; // Orange
string colorCode = $"#{r:X2}{g:X2}{b:X2}";
Console.WriteLine($"Color Code: {colorCode}");
Color Code: #FFA500
ハッシュ値の表示
SHA256などのハッシュアルゴリズムの結果は、通常バイト配列で返されます。
これをユーザーが読みやすい16進数文字列に変換して表示するのが一般的です。
using System.Security.Cryptography;
using System.Text;
byte[] inputBytes = Encoding.UTF8.GetBytes("Hello World");
byte[] hashBytes = SHA256.HashData(inputBytes);
// Convert.ToHexStringで一括変換
string hashHex = Convert.ToHexString(hashBytes);
Console.WriteLine($"SHA256: {hashHex}");
SHA256: A591A6D40BF420404A011733CFB7B190D62C65BF0BCDA32B57B277D9AD9F146E
まとめ
C#における16進数文字列への変換は、ToStringメソッドの書式指定子「X」を使いこなすことが基本となります。
単純な表示であれば、文字列補完を利用した記述が最も簡潔でメンテナンス性に優れています。
一方で、バイト配列全体を扱う場合や、高いパフォーマンスが求められる場合には、Convert.ToHexStringやSpan<char>といった専用の機能を活用することが重要です。
また、逆変換の際にはプレフィックス「0x」の有無に応じた適切なメソッド選択が必要になることを忘れないでください。
これらの手法を適切に使い分けることで、データの可視性を高め、効率的なプログラムを構築できるようになります。
この記事で紹介した各種テクニックを参考に、ぜひ日々のコーディングに役立ててください。
