C#における16進数文字列(string)とバイト(byte)の相互変換について知っておく。
ソースコード
byte から string へは BitConverter.ToString(byteData)
で変換できる。
でも逆の変換はライブラリにないので、自分で書く必要がある。
大体以下のような感じになると思う。
using System;
using System.Globalization;
public static byte[] HexStringToBytes(string s)
{
if (s == null)
{
throw new ArgumentNullException();
}
// 入力文字列の長さは偶数であること
if (s.Length % 2 != 0)
{
throw new FormatException();
}
// 長さ0は空を返す
if (s.Length == 0)
{
return Array.Empty<byte>();
}
// 半分の長さのバイト列ができる
var bytes = new byte[s.Length / 2];
for (int i = 0; i < bytes.Length; i++)
{
bytes[i] = byte.Parse(s.AsSpan().Slice(i*2, 2), NumberStyles.AllowHexSpecifier);
}
return bytes;
}
簡単に解説
まず入力チェックで、NULLはダメ。
長さについて、1バイトは二つの16進数文字で構成されるので、バイト配列に変換しようとしている文字列の長さは偶数のはず。
ということで奇数長はフォーマット誤りとする。
例外にメッセージ付けた方が良いかもしれない。
長さ0は何もせずに空配列を返す。
new byte[0]
でも良いのかもしれないが、わざわざ用意されたっぽいのでArray.Empty<>
を使っておく。
変換処理について、
入力文字列の半分の長さのバイト配列ができるので、必要な配列を用意して値を格納していく。
それぞれの型にはParse()
メソッドが用意されているので、それ(byte.Parse()
)を使って変換する。
Parseデータとして、Substring()
ではなくSpan<>
(ReadOnlySpan<>
)で部分文字列を渡す。
Span<>
は今のstringの内容をそのまま参照(Substring()
は新たなstringを生成)するので早いのだそう。
2番目の引数はドキュメント見たら丁度よいのがあったので、そのままコピペ。
(onvert.ToBytes(string, 16)
というやり方もあった。そっちのほうが普通なのかもしれない)
以上。