本文翻译自:byte[] to hex string [duplicate]
How do I convert a byte[] to a string ? 如何将byte[]转换为string ? Every time I attempt it, I get 每次尝试,我都会得到
System.Byte[] System.Byte []
instead of the value. 而不是价值。
Also, how do I get the value in Hex instead of a decimal? 另外,如何获取十六进制而不是十进制的值?
#1楼
参考:https://stackoom.com/question/2c64/byte-转换为十六进制字符串-重复
#2楼
I thought I would attempt to compare the speed of each of the methods listed here for the hell of it. 我以为我会比较这里列出的每种方法的速度。 I based the speed testing code off this. 我以此为基础建立了速度测试代码。
The result is that BitConverter+String.Replace seems to be faster than most other simple ways. 结果是BitConverter + String.Replace似乎比大多数其他简单方法都快。 But the speed can be improved with algorithms like Nathan Moinvaziri's ByteArrayToHexString or Kurt's ToHex. 但是可以使用Nathan Moinvaziri的ByteArrayToHexString或Kurt的ToHex之类的算法来提高速度。
I also found it interesting that string.Concat and string.Join are much slower than StringBuilder implementations for long strings, but similar for shorter arrays. 我也发现有趣的是,对于长字符串,string.Concat和string.Join比StringBuilder实现慢得多,但对于较短的数组则类似。 Probably due to expanding the StringBuilder on the longer strings, so setting the initial size should negate this difference. 可能是由于在较长的字符串上扩展了StringBuilder,因此设置初始大小应该可以消除这种差异。
- Took each bit of code from an answer here: 从这里得到答案的每一段代码:
- BitConvertRep = Answer by Guffa, BitConverter and String.Replace (I'd recommend for most cases) BitConvertRep = Guffa,BitConverter和String.Replace的答案(在大多数情况下,我建议使用)
- StringBuilder = Answer by Quintin Robinson, foreach char StringBuilder.Append StringBuilder = Quintin Robinson的答案,foreach char StringBuilder.Append
- LinqConcat = Answer by Michael Buen, string.Concat of Linq built array LinqConcat = Michael Buen的答案,字符串。Linq的Concat构建了数组
- LinqJoin = Answer by mloskot, string.Join of Linq built array LinqJoin = mloskot的答案,字符串。Linq的连接建立数组
- LinqAgg = Answer by Matthew Whited, IEnumerable.Aggregate with StringBuilder LinqAgg = IEnumerable的Matthew Whited的答案。与StringBuilder 聚合
- ToHex = Answer by Kurt, sets chars in an array, using byte values to get hex ToHex = Kurt的答案,在数组中设置字符,使用字节值获取十六进制
- ByteArrayToHexString = Answer by Nathan Moinvaziri, approx same speed as the ToHex above, and is probably easier to read (I'd recommend for speed) ByteArrayToHexString = Nathan Moinvaziri的回答,与上述ToHex的速度大致相同,并且可能更易于阅读(我建议您提高速度)
- ToHexFromTable = Linked in answer by Nathan Moinvaziri, for me this is near the same speed as the above 2 but requires an array of 256 strings to always exist ToHexFromTable =内森·莫因瓦济里(Nathan Moinvaziri)的答案链接,对我来说,这几乎与上述2相同的速度,但始终需要256个字符串数组
With:
LONG_STRING_LENGTH = 1000 * 1024;使用:LONG_STRING_LENGTH = 1000 * 1024;
- BitConvertRep calculation Time Elapsed 27,202 ms (fastest built in/simple) BitConvertRep计算经过的时间27,202 ms (内置/简单最快)
- StringBuilder calculation Time Elapsed 75,723 ms (StringBuilder no reallocate) StringBuilder计算经过的时间75,723毫秒(StringBuilder无需重新分配)
- LinqConcat calculation Time Elapsed 182,094 ms LinqConcat计算经过的时间182,094 ms
- LinqJoin calculation Time Elapsed 181,142 ms LinqJoin计算经过的时间181,142 ms
- LinqAgg calculation Time Elapsed 93,087 ms (StringBuilder with reallocating) LinqAgg计算经过的时间93,087 ms(带有重新分配的StringBuilder)
- ToHex calculation Time Elapsed 19,167 ms (fastest) ToHex计算经过的时间19,167 ms (最快)
With:
LONG_STRING_LENGTH = 100 * 1024;其中:LONG_STRING_LENGTH = 100 * 1024;, Similar results ,类似结果
- BitConvertReplace calculation Time Elapsed 3431 ms BitConvertReplace计算经过的时间3431 ms
- StringBuilder calculation Time Elapsed 8289 ms StringBuilder计算经过的时间8289 ms
- LinqConcat calculation Time Elapsed 21512 ms LinqConcat计算经过的时间21512 ms
- LinqJoin calculation Time Elapsed 19433 ms LinqJoin计算经过的时间19433 ms
- LinqAgg calculation Time Elapsed 9230 ms LinqAgg计算经过的时间9230 ms
- ToHex calculation Time Elapsed 1976 ms ToHex计算经过的时间1976 ms
With:
int MANY_STRING_COUNT = 1000;使用:int MANY_STRING_COUNT = 1000;int MANY_STRING_LENGTH = 1024;(Same byte count as first test but in different arrays) (与第一次测试相同的字节数,但使用不同的数组)
- BitConvertReplace calculation Time Elapsed 25,680 ms BitConvertReplace计算经过的时间25,680毫秒
- StringBuilder calculation Time Elapsed 78,411 ms StringBuilder计算经过的时间78,411 ms
- LinqConcat calculation Time Elapsed 101,233 ms LinqConcat计算经过的时间101,233 ms
- LinqJoin calculation Time Elapsed 99,311 ms LinqJoin计算经过的时间99,311 ms
- LinqAgg calculation Time Elapsed 84,660 ms LinqAgg计算经过的时间84,660 ms
- ToHex calculation Time Elapsed 18,221 ms ToHex计算经过的时间18,221 ms
With:
int MANY_STRING_COUNT = 2000;使用:int MANY_STRING_COUNT = 2000;int MANY_STRING_LENGTH = 20;
- BitConvertReplace calculation Time Elapsed 1347 ms BitConvertReplace计算经过的时间1347 ms
- StringBuilder calculation Time Elapsed 3234 ms StringBuilder计算经过的时间3234 ms
- LinqConcat calculation Time Elapsed 5013 ms LinqConcat计算经过的时间5013 ms
- LinqJoin calculation Time Elapsed 4826 ms LinqJoin计算经过的时间4826 ms
- LinqAgg calculation Time Elapsed 3589 ms LinqAgg计算经过的时间3589 ms
- ToHex calculation Time Elapsed 772 ms ToHex计算经过的时间772毫秒
Testing code I used: 我使用的测试代码:
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();
}
Also another answer with a similar process , I haven't compared our results yet. 另外一个具有类似过程的答案 ,我还没有比较我们的结果。
#3楼
With: 带有:
byte[] data = new byte[] { 0x01, 0x02, 0x03, 0x0D, 0x0E, 0x0F };
string hex = string.Empty;
data.ToList().ForEach(b => hex += b.ToString("x2"));
// use "X2" for uppercase hex letters
Console.WriteLine(hex);
Result: 0102030d0e0f 结果: 0102030d0e0f
#4楼
private static string GuidToRaw(Guid guid)
{
byte[] bytes = guid.ToByteArray();
int сharCount = bytes.Length * 2;
char[] chars = new char[сharCount];
int index = 0;
for (int i = 0; i < сharCount; i += 2)
{
byte b = bytes[index++];
chars[i] = GetHexValue((int)(b / 16));
chars[i + 1] = GetHexValue((int)(b % 16));
}
return new string(chars, 0, chars.Length);
}
private static char GetHexValue(int i)
{
return (char)(i < 10 ? i + 48 : i + 55);
}
#5楼
I think I made a faster byte array to string convertor: 我想我做了一个更快的字节数组到字符串转换器:
public static class HexTable
{
private static readonly string[] table = BitConverter.ToString(Enumerable.Range(0, 256).Select(x => (byte)x).ToArray()).Split('-');
public static string ToHexTable(byte[] value)
{
StringBuilder sb = new StringBuilder(2 * value.Length);
for (int i = 0; i < value.Length; i++)
sb.Append(table[value[i]]);
return sb.ToString();
}
And the test set up: 并进行测试设置:
static void Main(string[] args)
{
const int TEST_COUNT = 10000;
const int BUFFER_LENGTH = 100000;
Random random = new Random();
Stopwatch sw = new Stopwatch();
Stopwatch sw2 = new Stopwatch();
byte[] buffer = new byte[BUFFER_LENGTH];
random.NextBytes(buffer);
sw.Start();
for (int j = 0; j < TEST_COUNT; j++)
HexTable.ToHexTable(buffer);
sw.Stop();
sw2.Start();
for (int j = 0; j < TEST_COUNT; j++)
ToHexChar.ToHex(buffer);
sw2.Stop();
Console.WriteLine("Hex Table Elapsed Milliseconds: {0}", sw.ElapsedMilliseconds);
Console.WriteLine("ToHex Elapsed Milliseconds: {0}", sw2.ElapsedMilliseconds);
}
The ToHexChar.ToHEx() method is the ToHex() method shown previously. ToHexChar.ToHEx()方法是前面显示的ToHex()方法。
Results are as follows: 结果如下:
HexTable = 11808 ms ToHEx = 12168ms HexTable = 11808 ms ToHEx = 12168ms
It may not look that much of a difference, but it's still faster :) 它看起来似乎没有太大的区别,但是仍然更快:)
#6楼
Just to add one more answer to the pile, there is a System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary class that I've used which can convert bytes to and from hex: 只是为了给堆增加一个答案,这里有一个System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary类,该类可以将字节与十六进制进行转换:
string hex = new SoapHexBinary(bytes).ToString();
byte[] bytes = SoapHexBinary.Parse(hex).Value;
Not sure how it compares (benchmark) to other implementations, but IMO it is pretty simple -- especially for converting from hex back into bytes. 不确定将其与其他实现进行比较(基准),但是IMO非常简单-尤其是从十六进制转换回字节时。
本文对比了多种将字节数组转换为十六进制字符串的方法,包括BitConverter、StringBuilder、Linq等,通过不同长度的数据集测试了各自的性能,发现BitConverter+String.Replace和特定算法如ToHex在多数情况下表现最佳。
7437

被折叠的 条评论
为什么被折叠?



