-
Notifications
You must be signed in to change notification settings - Fork 58
/
Copy pathHexString.cs
135 lines (126 loc) · 5.26 KB
/
HexString.cs
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Ipfs
{
/// <summary>
/// A codec for <see href="https://en.wikipedia.org/wiki/Hexadecimal">Hexadecimal</see>.
/// </summary>
/// <remarks>
/// <para>
/// A codec for a hexadecimal string, <see cref="Encode"/> and <see cref="Decode"/>. Adds the extension method <see cref="ToHexString"/>
/// to encode a byte array and <see cref="ToHexBuffer"/> to decode a hexadecimal <see cref="string"/>.
/// </para>
/// </remarks>
public static class HexString
{
static readonly string[] LowerCaseHexStrings =
Enumerable.Range(byte.MinValue, byte.MaxValue + 1)
.Select(v => v.ToString("x2"))
.ToArray();
static readonly string[] UpperCaseHexStrings =
Enumerable.Range(byte.MinValue, byte.MaxValue + 1)
.Select(v => v.ToString("X2"))
.ToArray();
static readonly Dictionary<string, byte> HexBytes =
Enumerable.Range(byte.MinValue, byte.MaxValue + 1)
.SelectMany(v => new [] {
new { Value = v, String = v.ToString("x2") } ,
new { Value = v, String = v.ToString("X2") }
} )
.Distinct()
.ToDictionary(v => v.String, v => (byte) v.Value);
/// <summary>
/// Converts an array of 8-bit unsigned integers to its equivalent hexadecimal string representation.
/// </summary>
/// <param name="buffer">
/// An array of <see cref="byte">8-bit unsigned integers</see>.
/// </param>
/// <param name="format">
/// One of the format specifiers ("G" and "x" for lower-case hex digits, or "X" for the upper-case).
/// The default is "G".
/// </param>
/// <returns>
/// The string representation, in hexadecimal, of the contents of <paramref name="buffer"/>.
/// </returns>
public static string Encode(byte[] buffer, string format = "G")
{
string[] hexStrings;
switch (format)
{
case "G":
case "x":
hexStrings = LowerCaseHexStrings;
break;
case "X":
hexStrings = UpperCaseHexStrings;
break;
default:
throw new FormatException(string.Format("Invalid HexString format '{0}', only 'G', 'x' or 'X' are allowed.", format));
}
StringBuilder s = new StringBuilder(buffer.Length * 2);
foreach (var v in buffer)
s.Append(hexStrings[v]);
return s.ToString();
}
/// <summary>
/// Converts an array of 8-bit unsigned integers to its equivalent hexadecimal string representation.
/// </summary>
/// <param name="buffer">
/// An array of <see cref="byte">8-bit unsigned integers</see>.
/// </param>
/// <param name="format">
/// One of the format specifiers ("G" and "x" for lower-case hex digits, or "X" for the upper-case).
/// The default is "G".
/// </param>
/// <returns>
/// The string representation, in hexadecimal, of the contents of <paramref name="buffer"/>.
/// </returns>
public static string ToHexString(this byte[] buffer, string format = "G")
{
return Encode(buffer, format);
}
/// <summary>
/// Converts the specified <see cref="string"/>, which encodes binary data as hexadecimal digits,
/// to an equivalent 8-bit unsigned integer array.
/// </summary>
/// <param name="s">
/// The hexadecimal string to convert.
/// </param>
/// <returns>
/// An array of 8-bit unsigned integers that is equivalent to <paramref name="s"/>.
/// </returns>
public static byte[] Decode(string s)
{
int n = s.Length;
if (n % 2 != 0)
throw new InvalidDataException("The hex string length must be a multiple of 2.");
var buffer = new byte[n / 2];
for (int i = 0, j = 0; i < n; i += 2, j++)
{
var hex = s.Substring(i, 2);
byte value;
if (!HexBytes.TryGetValue(hex, out value))
throw new InvalidDataException(string.Format("'{0}' is not a valid hexadecimal byte.", hex));
buffer[j] = value;
}
return buffer;
}
/// <summary>
/// Converts the specified <see cref="string"/>, which encodes binary data as a hexadecimal string,
/// to an equivalent 8-bit unsigned integer array.
/// </summary>
/// <param name="s">
/// The hexadecimal string to convert.
/// </param>
/// <returns>
/// An array of 8-bit unsigned integers that is equivalent to <paramref name="s"/>.
/// </returns>
public static byte[] ToHexBuffer(this string s)
{
return Decode(s);
}
}
}