如何将字节数组转换为十六进制字符串,反之亦然?


当前回答

我怀疑这样的速度会使大多数其他测试失败。。。

Public Function BufToHex(ByVal buf() As Byte) As String
    Dim sB As New System.Text.StringBuilder
    For i As Integer = 0 To buf.Length - 1
        sB.Append(buf(i).ToString("x2"))
    Next i
    Return sB.ToString
End Function

其他回答

扩展方法(免责声明:完全未经测试的代码,BTW…):

public static class ByteExtensions
{
    public static string ToHexString(this byte[] ba)
    {
        StringBuilder hex = new StringBuilder(ba.Length * 2);

        foreach (byte b in ba)
        {
            hex.AppendFormat("{0:x2}", b);
        }
        return hex.ToString();
    }
}

使用Tomalak的三种解决方案之一(最后一种是字符串上的扩展方法)。

还有XmlWriter.WriteBinHex(请参见MSDN页面)。如果需要将十六进制字符串放入XML流中,这非常有用。

下面是一个独立的方法来了解它的工作原理:

    public static string ToBinHex(byte[] bytes)
    {
        XmlWriterSettings xmlWriterSettings = new XmlWriterSettings();
        xmlWriterSettings.ConformanceLevel = ConformanceLevel.Fragment;
        xmlWriterSettings.CheckCharacters = false;
        xmlWriterSettings.Encoding = ASCIIEncoding.ASCII;
        MemoryStream memoryStream = new MemoryStream();
        using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream, xmlWriterSettings))
        {
            xmlWriter.WriteBinHex(bytes, 0, bytes.Length);
        }
        return Encoding.ASCII.GetString(memoryStream.ToArray());
    }

支持最短路径和.net核心:

    public static string BytesToString(byte[] ba) =>
        ba.Aggregate(new StringBuilder(32), (sb, b) => sb.Append(b.ToString("X2"))).ToString();
    // a safe version of the lookup solution:       

    public static string ByteArrayToHexViaLookup32Safe(byte[] bytes, bool withZeroX)
    {
        if (bytes.Length == 0)
        {
            return withZeroX ? "0x" : "";
        }

        int length = bytes.Length * 2 + (withZeroX ? 2 : 0);
        StateSmall stateToPass = new StateSmall(bytes, withZeroX);
        return string.Create(length, stateToPass, (chars, state) =>
        {
            int offset0x = 0;
            if (state.WithZeroX)
            {
                chars[0] = '0';
                chars[1] = 'x';
                offset0x += 2;
            }

            Span<uint> charsAsInts = MemoryMarshal.Cast<char, uint>(chars.Slice(offset0x));
            int targetLength = state.Bytes.Length;
            for (int i = 0; i < targetLength; i += 1)
            {
                uint val = Lookup32[state.Bytes[i]];
                charsAsInts[i] = val;
            }
        });
    }

    private struct StateSmall
    {
        public StateSmall(byte[] bytes, bool withZeroX)
        {
            Bytes = bytes;
            WithZeroX = withZeroX;
        }

        public byte[] Bytes;
        public bool WithZeroX;
    }

就速度而言,这似乎比这里的任何东西都要好:

  public static string ToHexString(byte[] data) {
    byte b;
    int i, j, k;
    int l = data.Length;
    char[] r = new char[l * 2];
    for (i = 0, j = 0; i < l; ++i) {
      b = data[i];
      k = b >> 4;
      r[j++] = (char)(k > 9 ? k + 0x37 : k + 0x30);
      k = b & 15;
      r[j++] = (char)(k > 9 ? k + 0x37 : k + 0x30);
    }
    return new string(r);
  }