如何将字节数组转换为十六进制字符串,反之亦然?
当前回答
扩展方法(免责声明:完全未经测试的代码,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的三种解决方案之一(最后一种是字符串上的扩展方法)。
其他回答
支持最短路径和.net核心:
public static string BytesToString(byte[] ba) =>
ba.Aggregate(new StringBuilder(32), (sb, b) => sb.Append(b.ToString("X2"))).ToString();
两个mashup,将两个半字节操作合并为一个。
可能非常有效的版本:
public static string ByteArrayToString2(byte[] ba)
{
char[] c = new char[ba.Length * 2];
for( int i = 0; i < ba.Length * 2; ++i)
{
byte b = (byte)((ba[i>>1] >> 4*((i&1)^1)) & 0xF);
c[i] = (char)(55 + b + (((b-10)>>31)&-7));
}
return new string( c );
}
Decadent linq与比特黑客版本:
public static string ByteArrayToString(byte[] ba)
{
return string.Concat( ba.SelectMany( b => new int[] { b >> 4, b & 0xF }).Select( b => (char)(55 + b + (((b-10)>>31)&-7))) );
}
并反转:
public static byte[] HexStringToByteArray( string s )
{
byte[] ab = new byte[s.Length>>1];
for( int i = 0; i < s.Length; i++ )
{
int b = s[i];
b = (b - '0') + ((('9' - b)>>31)&-7);
ab[i>>1] |= (byte)(b << 4*((i&1)^1));
}
return ab;
}
如果您希望比BitConverter更灵活,但不希望使用那些笨重的90年代风格的显式循环,那么您可以这样做:
String.Join(String.Empty, Array.ConvertAll(bytes, x => x.ToString("X2")));
或者,如果您使用的是.NET 4.0:
String.Concat(Array.ConvertAll(bytes, x => x.ToString("X2")));
(后者来自对原帖子的评论。)
有一个简单的一行解决方案尚未提及,它将十六进制字符串转换为字节数组(我们不在乎这里的否定解释,因为这无关紧要):
BigInteger.Parse(str, System.Globalization.NumberStyles.HexNumber).ToByteArray().Reverse().ToArray();
此版本的ByteArrayToHexViaByteManipulation可能更快。
从我的报告中:
ByteArrayToHexViaByteManipulation3:1.68次平均滴答声(超过1000次),17,5XByteArrayToHexViaByteManipulation2:1,73平均滴答(超过1000次),16,9XByteArrayToHexViaByteManipulation:2,90平均刻度(超过1000次),10,1XByteArrayToHexViaLookupAndShift:3.22平均刻度(超过1000次),9,1X...静态专用只读字符[]hexAlphabet=新字符[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};静态字符串ByteArrayToHexViaByteManipulation3(byte[]字节){char[]c=新字符[bytes.Length*2];字节b;for(int i=0;i<bytes.Length;i++){b=((字节)(字节[i]>>4));c[i*2]=十六进制字母[b];b=((字节)(字节[i]&0xF));c[i*2+1]=十六进制字母[b];}返回新字符串(c);}
我认为这是一个优化:
static private readonly char[] hexAlphabet = new char[]
{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
static string ByteArrayToHexViaByteManipulation4(byte[] bytes)
{
char[] c = new char[bytes.Length * 2];
for (int i = 0, ptr = 0; i < bytes.Length; i++, ptr += 2)
{
byte b = bytes[i];
c[ptr] = hexAlphabet[b >> 4];
c[ptr + 1] = hexAlphabet[b & 0xF];
}
return new string(c);
}
推荐文章
- net HttpClient。如何POST字符串值?
- 我如何使一个方法的返回类型泛型?
- 何时处理CancellationTokenSource?
- 如何获取正在执行的程序集版本?
- AutoMapper vs valueinjector
- 为什么控制台不。Writeline,控制台。在Visual Studio Express中编写工作?
- 什么是.NET程序集?
- 字符串不能识别为有效的日期时间“格式dd/MM/yyyy”
- 函数应该返回空对象还是空对象?
- 如何转换日期时间?将日期时间
- 如何在c#中连接列表?
- 在c#中引用类型变量的“ref”的用途是什么?
- 在JavaScript中根据键值查找和删除数组中的对象
- 防止在ASP中缓存。NET MVC中使用属性的特定操作
- 如何确定一个数组是否包含另一个数组的所有元素