关于C#:字节[]到十六进制字符串

byte[] to hex string

本问题已经有最佳答案,请猛点这里访问。

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

System.Byte[]

而不是值。

另外,如何获得十六进制而不是十进制的值?


这有一个内置方法:

1
2
3
byte[] data = { 1, 2, 4, 8, 16, 32 };

string hex = BitConverter.ToString(data);

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

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

1
string hex = BitConverter.ToString(data).Replace("-", string.Empty);

结果:010204081020

如果需要更紧凑的表示,可以使用base64:

1
string base64 = Convert.ToBase64String(data);

结果:aqiebag


我想我会尝试比较这里列出的每种方法的速度。我把速度测试代码建立在这个基础上。

结果是bitconverter+string.replace似乎比大多数其他简单方法都要快。但是速度可以通过像内森·莫尼瓦齐里的byterraytohexstring或库尔特的tohex这样的算法来提高。

我还发现string.concat和string.join比长字符串的StringBuilder实现慢得多,但与短数组类似。可能是因为在较长的字符串上扩展了StringBuilder,所以设置初始大小应该会消除这一差异。

  • 从这里的答案中获取每一位代码:
  • bitconvertrep=用guffa、bitconverter和string回答。替换(我建议大多数情况下使用)
  • stringbuilder=由Quintin Robinson回答,foreach char stringbuilder.append
  • linq concat=由michael buen回答,string.concat of linq build array
  • linq join=mloskot应答,string.linq构建数组的join
  • linqagg=由Matthew Whited回答,IEnumerable.Aggregate with StringBuilder
  • to hex=按kurt应答,在数组中设置字符,使用字节值获取hex
  • bytearraytohexstring=由nathan moinvaziri回答,与上面的tohex速度大致相同,并且可能更容易阅读(我建议使用速度)
  • tohexfromtable=由nathan moinvaziri响应链接,对于我来说,这与上面的2接近,但需要256个字符串数组才能始终存在。

With: LONG_STRING_LENGTH = 1000 * 1024;

  • BitConvertRep calculation Time Elapsed 27,202 ms (fastest built in/simple)
  • StringBuilder calculation Time Elapsed 75,723 ms (StringBuilder no reallocate)
  • LinqConcat calculation Time Elapsed 182,094 ms
  • LinqJoin calculation Time Elapsed 181,142 ms
  • LinqAgg calculation Time Elapsed 93,087 ms (StringBuilder with reallocating)
  • ToHex calculation Time Elapsed 19,167 ms (fastest)

With: LONG_STRING_LENGTH = 100 * 1024;, Similar results

  • BitConvertReplace calculation Time Elapsed 3431 ms
  • StringBuilder calculation Time Elapsed 8289 ms
  • LinqConcat calculation Time Elapsed 21512 ms
  • LinqJoin calculation Time Elapsed 19433 ms
  • LinqAgg calculation Time Elapsed 9230 ms
  • ToHex calculation Time Elapsed 1976 ms

With: 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
  • StringBuilder calculation Time Elapsed 78,411 ms
  • LinqConcat calculation Time Elapsed 101,233 ms
  • LinqJoin calculation Time Elapsed 99,311 ms
  • LinqAgg calculation Time Elapsed 84,660 ms
  • ToHex calculation Time Elapsed 18,221 ms

With: int MANY_STRING_COUNT = 2000; int MANY_STRING_LENGTH = 20;

  • BitConvertReplace calculation Time Elapsed 1347 ms
  • StringBuilder calculation Time Elapsed 3234 ms
  • LinqConcat calculation Time Elapsed 5013 ms
  • LinqJoin calculation Time Elapsed 4826 ms
  • LinqAgg calculation Time Elapsed 3589 ms
  • ToHex calculation Time Elapsed 772 ms

我使用的测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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();
}

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


十六、六问府:

1
string.Concat(ba.Select(b => b.ToString("X2")).ToArray())

与时俱进

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

这个代码…

1
2
3
4
5
6
7
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);

…在.NET 4.0之前,输出为:

1
2
System.Linq.Enumerable+<CreateSelectIterator>c__Iterator10`2[System.Byte,System.String]
010204081020

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

1
2
010204081020
010204081020

在4.0之前,ba.Select(b => b.ToString("X2"))会过载(object arg0)IEnumerable会过载,即(params string[] values),我们需要将IEnumerable转换为字符串数组。在4.0之前,string.concat有10个重载函数,在4.0上现在是12个


另一种方法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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();
}

public static byte[] HexStringToByteArray(string Hex)
{
    byte[] Bytes = new byte[Hex.Length / 2];
    int[] HexValue = new int[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
       0x06, 0x07, 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F };

    for (int x = 0, i = 0; i < Hex.Length; i += 2, x += 1)
    {
        Bytes[x] = (byte)(HexValue[Char.ToUpper(Hex[i + 0]) - '0'] << 4 |
                          HexValue[Char.ToUpper(Hex[i + 1]) - '0']);
    }

    return Bytes;
}

或者,您可以像这样预先构建翻译表,以获得更快的结果:

http://blogs.msdn.com/b/blambert/archive/2009/02/22/blambert-codesnip-fast-byte-array-to-hex-string-conversion.aspx


我喜欢对这样的转换使用扩展方法,即使它们只是包装标准库方法。在十六进制转换的情况下,我使用以下手动调谐(即快速)算法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public static string ToHex(this 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 + 0x37 + 0x20 : b + 0x30);

        b = ((byte)(bytes[bx] & 0x0F));
        c[++cx]=(char)(b > 9 ? b + 0x37 + 0x20 : b + 0x30);
    }

    return new string(c);
}

public static byte[] HexToBytes(this string str)
{
    if (str.Length == 0 || str.Length % 2 != 0)
        return new byte[0];

    byte[] buffer = new byte[str.Length / 2];
    char c;
    for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx)
    {
        // Convert first half of byte
        c = str[sx];
        buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0')) << 4);

        // Convert second half of byte
        c = str[++sx];
        buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? (c - 'a' + 10) : (c - 'A' + 10)) : (c - '0'));
    }

    return buffer;
}

我不经常把字节转换成十六进制,所以我不得不说我不知道是否有更好的方法,但这里有一种方法。

1
2
3
4
5
StringBuilder sb = new StringBuilder();
foreach (byte b in myByteArray)
    sb.Append(b.ToString("X2"));

string hexString = sb.ToString();


我想我应该提供一个答案。从我的测试,这是最快的方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static class Helper
{
    public static string[] HexTbl = Enumerable.Range(0, 256).Select(v => v.ToString("X2")).ToArray();
    public static string ToHex(this IEnumerable<byte> array)
    {
        StringBuilder s = new StringBuilder();
        foreach (var v in array)
            s.Append(HexTbl[v]);
        return s.ToString();
    }
    public static string ToHex(this byte[] array)
    {
        StringBuilder s = new StringBuilder(array.Length*2);
        foreach (var v in array)
            s.Append(HexTbl[v]);
        return s.ToString();
    }
}


非常快(与反转):扩展方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public static class ExtensionMethods {
    public static string ToHex(this byte[] data) {
        return ToHex(data,"");
    }
    public static string ToHex(this byte[] data, string prefix) {
        char[] lookup = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        int i = 0, p = prefix.Length, l = data.Length;
        char[] c = new char[l * 2 + p];
        byte d;
        for(; i < p; ++i) c[i] = prefix[i];
        i = -1;
        --l;
        --p;
        while(i < l) {
            d = data[++i];
            c[++p] = lookup[d >> 4];
            c[++p] = lookup[d & 0xF];
        }
        return new string(c, 0, c.Length);
    }
    public static byte[] FromHex(this string str) {
        return FromHex(str, 0, 0, 0);
    }
    public static byte[] FromHex(this string str, int offset, int step) {
        return FromHex(str, offset, step, 0);
    }
    public static byte[] FromHex(this string str, int offset, int step, int tail) {
        byte[] b = new byte[(str.Length - offset - tail + step) / (2 + step)];
        byte c1, c2;
        int l = str.Length - tail;
        int s = step + 1;
        for(int y = 0, x = offset; x < l; ++y, x += s) {
            c1 = (byte)str[x];
            if(c1 > 0x60) c1 -= 0x57;
            else if(c1 > 0x40) c1 -= 0x37;
            else c1 -= 0x30;
            c2 = (byte)str[++x];
            if(c2 > 0x60) c2 -= 0x57;
            else if(c2 > 0x40) c2 -= 0x37;
            else c2 -= 0x30;
            b[y] = (byte)((c1 << 4) + c2);
        }
        return b;
    }
}

击败所有人之上的:在速度测试

=== Long string test
BitConvertReplace calculation Time Elapsed 2415 ms
StringBuilder calculation Time Elapsed 5668 ms
LinqConcat calculation Time Elapsed 11826 ms
LinqJoin calculation Time Elapsed 9323 ms
LinqAgg calculation Time Elapsed 7444 ms
ToHexTable calculation Time Elapsed 1028 ms
ToHexAcidzombie calculation Time Elapsed 1035 ms
ToHexPatrick calculation Time Elapsed 814 ms
ToHexKurt calculation Time Elapsed 1604 ms
ByteArrayToHexString calculation Time Elapsed 1330 ms

=== Many string test
BitConvertReplace calculation Time Elapsed 2238 ms
StringBuilder calculation Time Elapsed 5393 ms
LinqConcat calculation Time Elapsed 9043 ms
LinqJoin calculation Time Elapsed 9131 ms
LinqAgg calculation Time Elapsed 7324 ms
ToHexTable calculation Time Elapsed 968 ms
ToHexAcidzombie calculation Time Elapsed 969 ms
ToHexPatrick calculation Time Elapsed 956 ms
ToHexKurt calculation Time Elapsed 1547 ms
ByteArrayToHexString calculation Time Elapsed 1277 ms


只是添加一个更多的答案的System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary桩,有一类,我可以使用的转换和从字节十六进制:

1
2
string hex = new SoapHexBinary(bytes).ToString();
byte[] bytes = SoapHexBinary.Parse(hex).Value;

不知道它是如何实现的(基准)比其他国际海事组织,但它是很简单的--特别是来自反向转换成十六进制字节。


资料:

1
2
3
4
5
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);

结果:0102030d0e0f


在这里提到的一个原因,为什么你得到的"system.byte [ ]"字符串值而不是,所以我会的。

当一个对象是implicitly浇到字符串,该程序将默认的对象,这是一public String ToString()继承的方法:从System.Object

1
2
3
4
public virtual string ToString()
{
    return this.GetType().ToString();
}

如果你发现,你往往可以简单地制作这种转换,你创建一个包装类,这样的操作系统:控制和方法

1
2
3
4
5
public override string ToString()
{
    // do the processing here
    // return the nicely formatted string
}

现在你每一次打印,这将让您的包装对象的价值而不是你来自this.GetType().ToString()的价值。


将LINQ与字符串方法结合使用:

1
2
3
4
string hex = string.Join("",
  bin.Select(
    bin => bin.ToString("X2")
      ).ToArray());


i认为i制造的速度到convertor:字节数组字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
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();
    }

在测试集上的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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);
    }

该方法是tohex tohexchar.tohex()()方法中所示。

结果如下:

hextable = 11808女士tohex = 12168ms

它的外观设计可能没有这么大的差异,但它仍然是:)。


您必须知道用字节表示的字符串的编码,但是您可以说System.Text.UTF8Encoding.GetString(bytes)System.Text.ASCIIEncoding.GetString(bytes)。(我是从内存中执行此操作的,因此API可能不完全正确,但它非常接近。)

有关第二个问题的答案,请参阅此问题。


我不知道你是这样做,需要的性能,但在这里是最快的方法来转换成十六进制字符串的字节[ ]:我能想到

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static readonly char[] hexchar = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
public static string HexStr(byte[] data, int offset, int len, bool space = false)
{
    int i = 0, k = 2;
    if (space) k++;
    var c = new char[len * k];
    while (i < len)
    {
        byte d = data[offset + i];
        c[i * k] = hexchar[d / 0x10];
        c[i * k + 1] = hexchar[d % 0x10];
        if (space && i < len - 1) c[i * k + 2] = ' ';
        i++;
    }
    return new string(c, 0, c.Length);
}

正如其他人所说,这取决于字节数组中值的编码。尽管如此,您需要非常小心地处理这类事情,或者您可以尝试转换未由所选编码处理的字节。

乔恩·斯基特有一篇关于.NET中的编码和Unicode的好文章。推荐阅读。


这里是字节数组(byte[])的扩展方法,例如,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
var b = new byte[] { 15, 22, 255, 84, 45, 65, 7, 28, 59, 10 };
Console.WriteLine(b.ToHexString());


public static class HexByteArrayExtensionMethods
{
    private const int AllocateThreshold = 256;
    private const string UpperHexChars ="0123456789ABCDEF";
    private const string LowerhexChars ="0123456789abcdef";
    private static string[] upperHexBytes;
    private static string[] lowerHexBytes;

    public static string ToHexString(this byte[] value)
    {
        return ToHexString(value, false);
    }

    public static string ToHexString(this byte[] value, bool upperCase)
    {
        if (value == null)
        {
            throw new ArgumentNullException("value");
        }

        if (value.Length == 0)
        {
            return string.Empty;
        }

        if (upperCase)
        {
            if (upperHexBytes != null)
            {
                return ToHexStringFast(value, upperHexBytes);
            }

            if (value.Length > AllocateThreshold)
            {
                return ToHexStringFast(value, UpperHexBytes);
            }

            return ToHexStringSlow(value, UpperHexChars);
        }

        if (lowerHexBytes != null)
        {
            return ToHexStringFast(value, lowerHexBytes);
        }

        if (value.Length > AllocateThreshold)
        {
            return ToHexStringFast(value, LowerHexBytes);
        }

        return ToHexStringSlow(value, LowerhexChars);
    }

    private static string ToHexStringSlow(byte[] value, string hexChars)
    {
        var hex = new char[value.Length * 2];
        int j = 0;

        for (var i = 0; i < value.Length; i++)
        {
            var b = value[i];
            hex[j++] = hexChars[b >> 4];
            hex[j++] = hexChars[b & 15];
        }

        return new string(hex);
    }

    private static string ToHexStringFast(byte[] value, string[] hexBytes)
    {
        var hex = new char[value.Length * 2];
        int j = 0;

        for (var i = 0; i < value.Length; i++)
        {
            var s = hexBytes[value[i]];
            hex[j++] = s[0];
            hex[j++] = s[1];
        }

        return new string(hex);
    }

    private static string[] UpperHexBytes
    {
        get
        {
            return (upperHexBytes ?? (upperHexBytes = new[] {
               "00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",
               "10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",
               "20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
               "30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",
               "40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",
               "50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
               "60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",
               "70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",
               "80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
               "90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",
               "A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",
               "B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
               "C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",
               "D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",
               "E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",
               "F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF" }));
        }
    }

    private static string[] LowerHexBytes
    {
        get
        {
            return (lowerHexBytes ?? (lowerHexBytes = new[] {
               "00","01","02","03","04","05","06","07","08","09","0a","0b","0c","0d","0e","0f",
               "10","11","12","13","14","15","16","17","18","19","1a","1b","1c","1d","1e","1f",
               "20","21","22","23","24","25","26","27","28","29","2a","2b","2c","2d","2e","2f",
               "30","31","32","33","34","35","36","37","38","39","3a","3b","3c","3d","3e","3f",
               "40","41","42","43","44","45","46","47","48","49","4a","4b","4c","4d","4e","4f",
               "50","51","52","53","54","55","56","57","58","59","5a","5b","5c","5d","5e","5f",
               "60","61","62","63","64","65","66","67","68","69","6a","6b","6c","6d","6e","6f",
               "70","71","72","73","74","75","76","77","78","79","7a","7b","7c","7d","7e","7f",
               "80","81","82","83","84","85","86","87","88","89","8a","8b","8c","8d","8e","8f",
               "90","91","92","93","94","95","96","97","98","99","9a","9b","9c","9d","9e","9f",
               "a0","a1","a2","a3","a4","a5","a6","a7","a8","a9","aa","ab","ac","ad","ae","af",
               "b0","b1","b2","b3","b4","b5","b6","b7","b8","b9","ba","bb","bc","bd","be","bf",
               "c0","c1","c2","c3","c4","c5","c6","c7","c8","c9","ca","cb","cc","cd","ce","cf",
               "d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","da","db","dc","dd","de","df",
               "e0","e1","e2","e3","e4","e5","e6","e7","e8","e9","ea","eb","ec","ed","ee","ef",
               "f0","f1","f2","f3","f4","f5","f6","f7","f8","f9","fa","fb","fc","fd","fe","ff" }));
        }
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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);
}

用Linq做这件事的好方法…

1
2
3
4
var data = new byte[] { 1, 2, 4, 8, 16, 32 };
var hexString = data.Aggregate(new StringBuilder(),
                               (sb,v)=>sb.Append(v.ToString("X2"))
                              ).ToString();