首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >byte[]到十六进制字符串

byte[]到十六进制字符串
EN

Stack Overflow用户
提问于 2009-03-08 05:20:00
回答 19查看 628.1K关注 0票数 366

如何将byte[]转换为string?每一次尝试,我都会得到

System.Byte[]

而不是价值。

此外,如何以十六进制代替十进制来获得值?

EN

回答 19

Stack Overflow用户

发布于 2009-03-08 06:56:19

有一个内置的方法用于此:

代码语言:javascript
复制
byte[] data = { 1, 2, 4, 8, 16, 32 };

string hex = BitConverter.ToString(data);

结果: 01-02-04-08-10-20

如果你想要它没有破折号,只需删除它们:

代码语言:javascript
复制
string hex = BitConverter.ToString(data).Replace("-", string.Empty);

结果: 010204081020

如果您想要更紧凑的表示,可以使用Base64:

代码语言:javascript
复制
string base64 = Convert.ToBase64String(data);

结果: AQIECBAg

票数 682
EN

Stack Overflow用户

发布于 2012-04-06 20:29:29

.Net5.0更新

感谢@antoninkriz的基准比较,我们可以看到Convert.ToHexString是今天最明显的赢家

使用Convert.ToHexString以外的任何东西都是愚蠢的。在我看来,它显然赢得了:可读性、性能、安全性。

其余部分是在2012年4月10日前:

我想我会尝试比较这里列出的每一种方法的速度。我的速度测试代码是基于这个。

其结果是,BitConverter+String.Replace似乎比大多数其他简单的方法更快。但是使用内森·莫瓦阿齐里的ByteArrayToHexString或Kurt的ToHex之类的算法可以提高速度。

我还发现,对于长字符串,string.Concat和string.Join要比StringBuilder实现慢得多,对于较短的数组,这一点也很有趣。可能是由于在较长的字符串上展开了StringBuilder,所以设置初始大小应该可以消除这种差异。

  • 从答案中提取每一段代码:
  • BitConvertRep = Guffa、BitConverter和String.Replace 的回答(在大多数情况下,我建议编辑:不能使用的地方)
  • StringBuilder = Quintin Robinson的答复,foreach char StringBuilder.Append
  • LinqConcat = Michael的答案,Linq的string.Concat
  • LinqJoin =由mloskot回答,Linq构建数组的string.Join
  • LinqAgg =马修·怀特的回答,IEnumerable.Aggregate和StringBuilder
  • ToHex =由Kurt回答,在数组中设置字符,使用字节值获取十六进制
  • ByteArrayToHexString = Nathan的回答,与上面的ToHex大致相同,并且可能更容易阅读(我建议使用速度,编辑:在您不能使用的地方)
  • ToHexFromTable = Nathan的回答,对我来说,这个速度与上面的2差不多,但需要一个由256个字符串组成的数组才能始终存在。

与:LONG_STRING_LENGTH = 1000 * 1024;

  • BitConvertRep计算时间经过27,202 ms (内置最快/简单)
  • StringBuilder计算时间为75,723 ms (StringBuilder未重新分配)
  • LinqConcat计算时间为182,094 ms
  • LinqJoin计算时间为181,142 ms
  • LinqAgg计算时间为93,087 ms (StringBuilder进行重新分配)
  • ToHex计算时间19,167 ms (最快)

With:LONG_STRING_LENGTH = 100 * 1024;,类似的结果

  • BitConvertReplace计算时间为3431 ms
  • StringBuilder计算时间为8289 ms
  • LinqConcat计算时间为21512 ms
  • LinqJoin计算时间为19433 ms
  • LinqAgg计算时间为9230 ms
  • ToHex计算时间间隔为1976年ms

With:int MANY_STRING_COUNT = 1000; int MANY_STRING_LENGTH = 1024; (与第一次测试相同的字节计数,但在不同的数组中)

  • BitConvertReplace计算时间为25,680 ms
  • StringBuilder计算时间为78 411 ms
  • LinqConcat计算时间为101,233 ms
  • LinqJoin计算时间为99,311 ms
  • LinqAgg计算时间为84 660 ms
  • ToHex计算时间为18 221 ms

电话:int MANY_STRING_COUNT = 2000; int MANY_STRING_LENGTH = 20;

  • BitConvertReplace计算时间经过1347 ms
  • StringBuilder计算时间为3234 ms
  • LinqConcat计算时间为5013 ms
  • LinqJoin计算时间为4826 ms
  • LinqAgg计算时间为3589 ms
  • ToHex计算时间为772 ms

我使用的测试代码:

代码语言:javascript
复制
void Main()
{
    int LONG_STRING_LENGTH = 100 * 1024;
    int MANY_STRING_COUNT = 1024;
    int MANY_STRING_LENGTH = 100;

    var source = GetRandomBytes(LONG_STRING_LENGTH);

    List<byte[]> manyString = new List<byte[]>(MANY_STRING_COUNT);
    for (int i = 0; i < MANY_STRING_COUNT; ++i)
    {
        manyString.Add(GetRandomBytes(MANY_STRING_LENGTH));
    }

    var algorithms = new Dictionary<string,Func<byte[], string>>();
    algorithms["BitConvertReplace"] = BitConv;
    algorithms["StringBuilder"] = StringBuilderTest;
    algorithms["LinqConcat"] = LinqConcat;
    algorithms["LinqJoin"] = LinqJoin;
    algorithms["LinqAgg"] = LinqAgg;
    algorithms["ToHex"] = ToHex;
    algorithms["ByteArrayToHexString"] = ByteArrayToHexString;

    Console.WriteLine(" === Long string test");
    foreach (var pair in algorithms) {
        TimeAction(pair.Key + " calculation", 500, () =>
        {
            pair.Value(source);
        });
    }

    Console.WriteLine(" === Many string test");
    foreach (var pair in algorithms) {
        TimeAction(pair.Key + " calculation", 500, () =>
        {
            foreach (var str in manyString)
            {
                pair.Value(str);
            }
        });
    }
}

// Define other methods and classes here
static void TimeAction(string description, int iterations, Action func) {
    var watch = new Stopwatch();
    watch.Start();
    for (int i = 0; i < iterations; i++) {
        func();
    }
    watch.Stop();
    Console.Write(description);
    Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}

//static byte[] GetRandomBytes(int count) {
//  var bytes = new byte[count];
//  (new Random()).NextBytes(bytes);
//  return bytes;
//}
static Random rand = new Random();
static byte[] GetRandomBytes(int count) {
    var bytes = new byte[count];
    rand.NextBytes(bytes);
    return bytes;
}


static string BitConv(byte[] data)
{
    return BitConverter.ToString(data).Replace("-", string.Empty);
}
static string StringBuilderTest(byte[] data)
{
    StringBuilder sb = new StringBuilder(data.Length*2);
    foreach (byte b in data)
        sb.Append(b.ToString("X2"));

    return sb.ToString();
}
static string LinqConcat(byte[] data)
{
    return string.Concat(data.Select(b => b.ToString("X2")).ToArray());
}
static string LinqJoin(byte[] data)
{
    return string.Join("",
        data.Select(
            bin => bin.ToString("X2")
            ).ToArray());
}
static string LinqAgg(byte[] data)
{
    return data.Aggregate(new StringBuilder(),
                               (sb,v)=>sb.Append(v.ToString("X2"))
                              ).ToString();
}
static string ToHex(byte[] bytes)
{
    char[] c = new char[bytes.Length * 2];

    byte b;

    for(int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx)
    {
        b = ((byte)(bytes[bx] >> 4));
        c[cx] = (char)(b > 9 ? b - 10 + 'A' : b + '0');

        b = ((byte)(bytes[bx] & 0x0F));
        c[++cx] = (char)(b > 9 ? b - 10 + 'A' : b + '0');
    }

    return new string(c);
}
public static string ByteArrayToHexString(byte[] Bytes)
{
    StringBuilder Result = new StringBuilder(Bytes.Length*2);
    string HexAlphabet = "0123456789ABCDEF";

    foreach (byte B in Bytes)
        {
        Result.Append(HexAlphabet[(int)(B >> 4)]);
        Result.Append(HexAlphabet[(int)(B & 0xF)]);
        }

    return Result.ToString();
}

还有另一个类似过程的答案,我还没有比较我们的结果。

票数 105
EN

Stack Overflow用户

发布于 2009-03-08 05:49:20

哈克斯,林奇福:

代码语言:javascript
复制
string.Concat(ba.Select(b => b.ToString("X2")).ToArray())

与时代的更新

正如@RubenBartelink所指出的,没有将IEnumerable<string>转换为数组的代码:ba.Select(b => b.ToString("X2"))在4.0之前不工作,现在相同的代码正在运行。

这个密码..。

代码语言:javascript
复制
byte[] ba = { 1, 2, 4, 8, 16, 32 };

string s = string.Concat(ba.Select(b => b.ToString("X2")));
string t = string.Concat(ba.Select(b => b.ToString("X2")).ToArray());

Console.WriteLine (s);
Console.WriteLine (t);

...prior到.NET 4.0的输出是:

代码语言:javascript
复制
System.Linq.Enumerable+<CreateSelectIterator>c__Iterator10`2[System.Byte,System.String]
010204081020

在.NET 4.0之后,string.Concat有一个接受IEnumerable的重载。因此,在4.0上,上述代码对于两个变量s和t具有相同的输出

代码语言:javascript
复制
010204081020
010204081020

在4.0之前,ba.Select(b => b.ToString("X2"))进入重载(object arg0)IEnumerable<string>要进行适当的重载,即(params string[] values),我们需要将IEnumerable<string>转换为string数组。在4.0之前,string.Concat有10个重载函数,在4.0上现在是12个

票数 80
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/623104

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档