none
バイナリデータを16進数のままテキストボックスに表示したい RRS feed

  • 質問

  • いつもお世話になっております。
    現在、バイナリ形式のパケットを受信し処理するプログラムを作成しています。
    受信したバイナリ形式のデータを、16進数のまま表示するにはどのようにすればよいでしょうか。
    受信したーデータはbyte型の配列に保存されています。とりあえず、ToStringメソッドを試してみましたが、System.Byte[]と表示されるだけでした。

    標準でこの要求に応えるメソッドの類はないでしょうか?
    2011年1月15日 9:22

回答

  • // 数値は数値であり、なんらかの形式を持っているわけではないので、「16 進数のまま」は妙な表現です。何進数というのは人が数字を見やすくする工夫でしかありません。

    簡単に変換するなら、BitConverter クラスの ToString 静的メソッドが使えるでしょう。バイト間はハイフンでつなげられますが、それが好ましくないなら Replace メソッドで置換してしまいましょう。

    もうちょっとこった変換をしたいのなら(いくつかごとに改行したいとか)、普通にループを回して一つずつ変換していくことになります。その際には、byte のインスタンスメソッドである ToString に書式指定文字列 を渡すなどします。

    • 回答としてマーク VANLILY 2011年1月15日 13:01
    2011年1月15日 9:36
  • デバッグ用途に限定なら問題ないかもしれませんが、ToString() は多機能ゆえにパフォーマンスが問題になることが多いので、16進数作成処理は独自に用意していることが多いですね。

    以下は GDN にも書いたことのある実装例です。標準の ToString() で16進数表記にすることと比較すると、それなりに高速なはずです。

      /// <summary>
      /// Primitive 型に対する拡張メソッド群
      /// </summary>
      public static partial class PrimitiveExtension
      {
        /// <summary>
        /// バイト列を16進数でダンプする
        /// </summary>
        /// <param name="bytes">ダンプ対象のバイト列</param>
        /// <returns>ダンプ結果</returns>
        public static string ToHexString(this byte[] bytes)
        {
          const string HEX = "0123456789ABCDEF";
          
          if (bytes == null)
            throw new ArgumentNullException("bytes");
    
          char[] dump = new char[bytes.Length * 2];
    
          for (int i = 0; i < bytes.Length; i++)
          {
            dump[i * 2 + 0] = HEX[bytes[i] >> 4];
            dump[i * 2 + 1] = HEX[bytes[i] & 15];
          }
    
          return new string(dump);
        }
      }
    
    
    • 回答としてマーク VANLILY 2011年1月22日 18:13
    2011年1月17日 1:11

すべての返信

  • // 数値は数値であり、なんらかの形式を持っているわけではないので、「16 進数のまま」は妙な表現です。何進数というのは人が数字を見やすくする工夫でしかありません。

    簡単に変換するなら、BitConverter クラスの ToString 静的メソッドが使えるでしょう。バイト間はハイフンでつなげられますが、それが好ましくないなら Replace メソッドで置換してしまいましょう。

    もうちょっとこった変換をしたいのなら(いくつかごとに改行したいとか)、普通にループを回して一つずつ変換していくことになります。その際には、byte のインスタンスメソッドである ToString に書式指定文字列 を渡すなどします。

    • 回答としてマーク VANLILY 2011年1月15日 13:01
    2011年1月15日 9:36
  • Hongliangさん、ご返信ありがとうございます。
    >>数値は数値であり、なんらかの形式を持っているわけではないので、「16 進数のまま」は妙な表現です。何進数というのは人が数字を見やすくする工夫でしかありません。
    現在、デバッグ機能つきでの開発を行っております。そのため、受信したバイナリパケットを正しく解釈、処理したかを確認するために、パケットの中身をそのまま表示する機能が必要でした。

    おっしゃるとおり、BitConverterクラスのToStringメソッドを使用することにします。ありがとうございました。
    2011年1月15日 13:04
  • デバッグ用途に限定なら問題ないかもしれませんが、ToString() は多機能ゆえにパフォーマンスが問題になることが多いので、16進数作成処理は独自に用意していることが多いですね。

    以下は GDN にも書いたことのある実装例です。標準の ToString() で16進数表記にすることと比較すると、それなりに高速なはずです。

      /// <summary>
      /// Primitive 型に対する拡張メソッド群
      /// </summary>
      public static partial class PrimitiveExtension
      {
        /// <summary>
        /// バイト列を16進数でダンプする
        /// </summary>
        /// <param name="bytes">ダンプ対象のバイト列</param>
        /// <returns>ダンプ結果</returns>
        public static string ToHexString(this byte[] bytes)
        {
          const string HEX = "0123456789ABCDEF";
          
          if (bytes == null)
            throw new ArgumentNullException("bytes");
    
          char[] dump = new char[bytes.Length * 2];
    
          for (int i = 0; i < bytes.Length; i++)
          {
            dump[i * 2 + 0] = HEX[bytes[i] >> 4];
            dump[i * 2 + 1] = HEX[bytes[i] & 15];
          }
    
          return new string(dump);
        }
      }
    
    
    • 回答としてマーク VANLILY 2011年1月22日 18:13
    2011年1月17日 1:11
  • K.Takaokaさん、ご返信ありがとうございます(すさまじく遅れてしまいましたが…)。
    質問に回答をいただいた後、Bitconverterのtostringを使用してプログラムを書きました。デバッグの段階を超えて、内部の効率化を図る段階にたどり着きましたら、ぜひ利用させていただきます。
    ありがとうございました。
    2011年1月22日 18:12