字节到hexstring

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

System.Byte []

而不是价值。

另外,我怎么得到hex的值,而不是一个小数?

有一个内置的方法:

 byte[] data = { 1, 2, 4, 8, 16, 32 }; string hex = BitConverter.ToString(data); 

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

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

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

结果:010204081020

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

 string base64 = Convert.ToBase64String(data); 

结果:AQIECBAg

我想我会试图比较这里列出的每种方法的速度。 我基于速度testing代码。

结果是BitConverter + String.Replace似乎比大多数其他简单的方法更快。 但速度可以用像Nathan Moinvaziri的ByteArrayToHexString或Kurt的ToHex 这样的algorithm来改进。

我还发现有趣的是,string.Concat和string.Join比StringBuilder实现对于长string要慢很多,但对于较短的数组来说却是相似的。 可能是由于在较长的string上扩展了StringBuilder,所以设置初始大小应该消除这种差异。

  • 从这里回答了每一个代码:
  • BitConvertRep =通过Guffa,BitConverter和String.Replace (我build议大多数情况下)
  • StringBuilder =通过Quintin Robinson,foreach char StringBuilder.Append
  • LinqConcat =回答Michael Buen,Linq的string.Concat构build的数组
  • LinqJoin =通过mloskot,string.JoinjoinLinq构build数组
  • LinqAgg =回答Matthew Whited ,IEnumerable.Aggregate与StringBuilder
  • ToHex =答案Kurt,设置一个数组中的字符,使用字节值来获取hex
  • ByteArrayToHexString =由Nathan Moinvaziri回答,与上面的ToHex大致相同,可能更容易阅读(我build议速度)
  • ToHexFromTable =由Nathan Moinvaziri回答链接,对我来说这是接近上述2的速度,但需要256个string的数组始终存在

有: LONG_STRING_LENGTH = 1000 * 1024;

  • BitConvertRep计算时间已用27,202毫秒 (最快内置/简单)
  • StringBuilder计算时间已用75,723毫秒(StringBuilder没有重新分配)
  • LinqConcat计算时间经过182,094 ms
  • Linqjoin计算时间已用181,142毫秒
  • LinqAgg计算时间已用93,087毫秒(StringBuilder与重新分配)
  • ToHex计算时间经过19,167毫秒 (最快)

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

  • BitConvertReplace计算时间经过3431毫秒
  • StringBuilder计算时间经过8289毫秒
  • LinqConcat计算时间经过21512毫秒
  • Linqjoin计算时间经过19433毫秒
  • LinqAgg计算时间经过9230毫秒
  • ToHex计算时间经过1976毫秒

用: int MANY_STRING_COUNT = 1000; int MANY_STRING_LENGTH = 1024; (与第一次testing相同的字节数,但在不同的arrays中)

  • BitConvertReplace计算时间已用25,680毫秒
  • StringBuilder计算时间已用78,411毫秒
  • LinqConcat计算时间已用101,233毫秒
  • Linqjoin计算时间已用99,311毫秒
  • LinqAgg计算时间已用84,660毫秒
  • ToHex计算时间经过18,221毫秒

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

  • BitConvertReplace计算时间经过1347毫秒
  • StringBuilder计算时间经过3234毫秒
  • LinqConcat计算时间已用5013毫秒
  • LinqJoin计算时间经过4826毫秒
  • LinqAgg计算时间经过3589毫秒
  • ToHex计算时间经过772毫秒

我使用的testing代码:

 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(); } 

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

Hex,Linq-fu:

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

与时代更新

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

这个代码…

 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之前,输出是:

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

在.NET 4.0之后,string.Concat有一个接受IEnumerable的重载。 因此,在4.0上面的代码将有相同的输出variabless和t

 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

我喜欢使用扩展方法进行转换,即使它们只是包装标准库方法。 在hex转换的情况下,我使用以下手动调整(即快速 )algorithm:

 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; } 

那么我不会经常转换字节为hex,所以我不得不说,我不知道是否有一个更好的方式,然而这是一个办法做到这一点。

 StringBuilder sb = new StringBuilder(); foreach (byte b in myByteArray) sb.Append(b.ToString("X2")); string hexString = sb.ToString(); 

这是另一种方法:

 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; } 

或者,您可以预先构build翻译表,以实现更快的结果:

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

我以为我应该提供一个答案。 从我的testing来看这个方法是最快的

 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(); } } 

非常快速的延伸方法(反转):

 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; } } 

在上面的速度testing中击败所有其他人:

===长串testing
BitConvertReplace计算时间已用2415毫秒
StringBuilder计算时间经过5668毫秒
LinqConcat计算时间经过11826毫秒
Linqjoin计算时间经过9323毫秒
LinqAgg计算时间经过7444毫秒
ToHexTable计算时间经过1028毫秒
ToHexAcidzombie计算时间经过1035毫秒
ToHexPatrick计算时间经过814毫秒
ToHexKurt计算时间已用1604毫秒
ByteArrayToHexString计算时间经过1330毫秒

===许多stringtesting
BitConvertReplace计算时间经过2238毫秒
StringBuilder计算时间已用5393毫秒
LinqConcat计算时间已用9043毫秒
Linqjoin计算时间经过9131毫秒
LinqAgg计算时间经过7324毫秒
ToHexTable计算时间经过968毫秒
ToHexAcidzombie计算时间经过969毫秒
ToHexPatrick计算时间经过956毫秒
ToHexKurt计算时间经过1547毫秒
ByteArrayToHexString计算时间经过1277毫秒

只是添加一个答案堆,我有一个System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary类,它可以将字节转换为和从hex:

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

不知道它如何比较(基准)到其他的实现,但IMO是非常简单的 – 特别是从hex转换回字节。

附:

 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

你把LINQ和string方法结合起来:

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

您必须知道以字节表示的string编码,但可以说System.Text.UTF8Encoding.GetString(bytes)System.Text.ASCIIEncoding.GetString(bytes) 。 (我是从内存这样做的,所以API可能不完全正确,但非常接近。)

对于你的第二个问题的答案,看到这个问题 。

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

Jon Skeet在.NET中有一个关于编码和unicode的好文章 。 推荐阅读。

我想我做了一个更快的字节数组string转换器:

 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(); } 

而testing设置:

 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); } 

ToHexChar.ToHEx()方法是前面显示的ToHex()方法。

结果如下:

HexTable = 11808毫秒ToHEx = 12168毫秒

它可能看起来没有什么区别,但它仍然更快:)

这里没有人提到你为什么得到“System.Byte []”string而不是值的原因,所以我会。

当一个对象被隐式转换为一个String时,程序将默认为从System.Objectinheritance的对象的public String ToString()方法:

 public virtual string ToString() { return this.GetType().ToString(); } 

如果你发现你经常进行这个转换,你可以简单地创build一个包装类并重写这个方法:

 public override string ToString() { // do the processing here // return the nicely formatted string } 

现在每次打印这个包装器对象时,你都会得到你的值,而不是this.GetType().ToString()

我不确定你是否需要这样做的性能,但这是最快的方法来转换字节[]为hexstring,我可以想到的:

 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); } 

用LINQ做这件事的好方法…

 var data = new byte[] { 1, 2, 4, 8, 16, 32 }; var hexString = data.Aggregate(new StringBuilder(), (sb,v)=>sb.Append(v.ToString("X2")) ).ToString(); 
 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); } 

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

 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" })); } } }