hexadecimal a decimal c#
byte[] a la cadena hexadecimal (19)
Esta pregunta ya tiene una respuesta aquí:
¿Cómo convierto un byte[]
a una string
? Cada vez que lo intento lo consigo.
System.Byte []
en lugar del valor.
Además, ¿cómo obtengo el valor en Hex en lugar de un decimal?
Aquí hay otro método:
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;
}
Alternativamente, puede preconstruir la tabla de traducción para lograr resultados aún más rápidos:
Aquí hay un método de extensión para la matriz de bytes (byte []), por ejemplo,
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" }));
}
}
}
Buena manera de hacer esto con 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();
Bueno, no convierto bytes a hexadecimal a menudo, así que tengo que decir que no sé si hay una mejor manera que esta, pero aquí hay una manera de hacerlo.
StringBuilder sb = new StringBuilder();
foreach (byte b in myByteArray)
sb.Append(b.ToString("X2"));
string hexString = sb.ToString();
Combinas LINQ con métodos de cadena:
string hex = string.Join("",
bin.Select(
bin => bin.ToString("X2")
).ToArray());
Como han dicho otros, depende de la codificación de los valores en la matriz de bytes. A pesar de esto, debe tener mucho cuidado con este tipo de cosas o puede intentar convertir los bytes que no son manejados por la codificación elegida.
Jon Skeet tiene un buen artículo sobre codificación y Unicode en .NET. Lectura recomendada.
Con:
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);
Resultado: 0102030d0e0f
Creo que hice una matriz de bytes más rápida al convertidor de cadena:
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();
}
Y la prueba de puesta en marcha:
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);
}
El método ToHexChar.ToHEx () es el método ToHex () que se mostró anteriormente.
Los resultados son los siguientes:
HexTable = 11808 ms ToHEx = 12168ms
Puede que no parezca una gran diferencia, pero aún es más rápido :)
Debe conocer la codificación de la cadena representada en bytes, pero puede decir System.Text.UTF8Encoding.GetString(bytes)
o System.Text.ASCIIEncoding.GetString(bytes)
. (Estoy haciendo esto desde la memoria, por lo que la API puede no ser exactamente correcta, pero está muy cerca).
Para la respuesta a su segunda pregunta, vea esta pregunta .
Hay un método incorporado para esto:
byte[] data = { 1, 2, 4, 8, 16, 32 };
string hex = BitConverter.ToString(data);
Resultado: 01-02-04-08-10-20
Si lo deseas sin los guiones, simplemente elimínalos:
string hex = BitConverter.ToString(data).Replace("-", string.Empty);
Resultado: 010204081020
Si quieres una representación más compacta, puedes usar Base64:
string base64 = Convert.ToBase64String(data);
Resultado: AQIECBAg
Hex, Linq-fu:
string.Concat(ba.Select(b => b.ToString("X2")).ToArray())
ACTUALIZAR con los tiempos
Como lo señaló @RubenBartelink, el código que no tiene una conversión de IEnumerable<string>
a una matriz: ba.Select(b => b.ToString("X2"))
no funciona antes de 4.0, el mismo código ahora está trabajando en 4.0.
Este código ...
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);
... antes de .NET 4.0, la salida es:
System.Linq.Enumerable+<CreateSelectIterator>c__Iterator10`2[System.Byte,System.String]
010204081020
En .NET 4.0 en adelante, string.Concat tiene una sobrecarga que acepta IEnumerable. Por lo tanto, en 4.0, el código anterior tendrá el mismo resultado para ambas variables sy t
010204081020
010204081020
Antes de 4.0, ba.Select(b => b.ToString("X2"))
va a la sobrecarga (object arg0)
, la forma en que la IEnumerable<string>
va a una sobrecarga apropiada, es decir (params string[] values)
, es que necesitamos convertir la IEnumerable<string>
a un array de cadenas. Antes de 4.0, string.Concat tiene 10 funciones de sobrecarga, en 4.0 ahora es 12
Métodos de extensión muy rápidos (con inversión):
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;
}
}
Supera a todos los demás en la prueba de velocidad anterior:
=== Prueba de cuerda larga
Tiempo de cálculo de BitConvertReplace transcurrido 2415 ms
Cálculo de StringBuilder Tiempo transcurrido 5668 ms
Cálculo LinqConcat Tiempo transcurrido 11826 ms
Cálculo de LinqJoin Tiempo transcurrido 9323 ms
LinqAgg calculo Tiempo transcurrido 7444 ms
Tiempo de cálculo de tabla de conversión transcurrió 1028 ms
ToHexAcidzombie calcula el tiempo transcurrido 1035 ms
ToHexPatrick calculo Tiempo transcurrido 814 ms
ToHexKurt cálculo Tiempo transcurrido 1604 ms
ByteArrayToHexString cálculo Tiempo transcurrido 1330 ms=== Muchas pruebas de cuerdas
BitConvertReplace tiempo de cálculo transcurrido 2238 ms
Tiempo de cálculo de StringBuilder transcurrido 5393 ms
Cálculo LinqConcat Tiempo transcurrido 9043 ms
Cálculo de LinqJoin Tiempo transcurrido 9131 ms
LinqAgg cálculo Tiempo transcurrido 7324 ms
Tiempo de cálculo de tabla de conversión transcurridos 968 ms
ToHexAcidzombie calcula el tiempo transcurrido 969 ms
ToHexPatrick calculo Tiempo transcurrido 956 ms
ToHexKurt cálculo Tiempo transcurrido 1547 ms
ByteArrayToHexString cálculo Tiempo transcurrido 1277 ms
Me gusta usar métodos de extensión para conversiones como esta, incluso si solo envuelven métodos de biblioteca estándar. En el caso de conversiones hexadecimales, uso los siguientes algoritmos ajustados a mano (es decir, rápidos ):
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;
}
Nadie mencionó aquí la razón por la que obtienes la cadena "System.Byte []" en lugar del valor, así que lo haré.
Cuando un objeto se convierte implícitamente en una cadena, el programa usará por defecto el método public String ToString()
que se hereda de System.Object
:
public virtual string ToString()
{
return this.GetType().ToString();
}
Si descubre que a menudo está realizando esta conversión, simplemente podría crear una clase contenedora y anular este método de la siguiente manera:
public override string ToString()
{
// do the processing here
// return the nicely formatted string
}
Ahora, cada vez que imprima este objeto contenedor, obtendrá su valor en lugar del valor de this.GetType().ToString()
.
No estoy seguro de si necesitas el rendimiento para hacer esto, pero este es el método más rápido para convertir bytes [] en cadenas hexadecimales en las que puedo pensar:
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);
}
Pensé que debería dar una respuesta. Desde mi prueba este método es el más rápido.
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();
}
}
Pensé que intentaría comparar la velocidad de cada uno de los métodos enumerados aquí por el gusto de hacerlo. Basé el código de prueba de velocidad de esto.
El resultado es que BitConverter + String.Replace parece ser más rápido que la mayoría de las otras formas simples. Pero la velocidad se puede mejorar con algoritmos como ByteArrayToHexString de Nathan Moinvaziri o ToHex de Kurt.
También me pareció interesante que string.Concat y string.Join son mucho más lentos que las implementaciones de StringBuilder para cadenas largas, pero similares para matrices más cortas. Probablemente debido a la expansión del StringBuilder en las cadenas más largas, por lo que establecer el tamaño inicial debería negar esta diferencia.
- Tomé cada bit de código de una respuesta aquí:
- BitConvertRep = Respuesta de Guffa, BitConverter y String.Replace (recomendaría para la mayoría de los casos)
- StringBuilder = Respuesta de Quintin Robinson, foreach char StringBuilder.Append
- LinqConcat = Respuesta de Michael Buen, string.Concat de Linq built array
- LinqJoin = Respuesta de mloskot, string.Join de Linq built array
- LinqAgg = Respuesta de Matthew Whited, IEnumerable.Aggregate with StringBuilder
- ToHex = Answer by Kurt, establece caracteres en una matriz, usando valores de bytes para obtener hexadecimal
- ByteArrayToHexString = Respuesta de Nathan Moinvaziri, aproximadamente a la misma velocidad que el ToHex anterior, y probablemente sea más fácil de leer (lo recomiendo para la velocidad)
- ToHexFromTable = Vinculado en respuesta por Nathan Moinvaziri, para mí esta es casi la misma velocidad que la anterior 2 pero requiere una matriz de 256 cadenas para que siempre exista
Con:
LONG_STRING_LENGTH = 1000 * 1024;
- Cálculo de BitConvertRep Tiempo transcurrido 27,202 ms (el más rápido incorporado / simple)
- Tiempo de cálculo de StringBuilder transcurrido 75.723 ms (StringBuilder sin reasignación)
- Cálculo de LinqConcat Tiempo transcurrido 182,094 ms
- Cálculo de LinqJoin Tiempo transcurrido 181,142 ms
- Cálculo de LinqAgg Tiempo transcurrido 93,087 ms (StringBuilder con reasignación)
- Cálculo de ToHex Tiempo transcurrido 19,167 ms (el más rápido)
Con:
LONG_STRING_LENGTH = 100 * 1024;
, Resultados similares
- BitConvertReplace calcula el tiempo transcurrido 3431 ms
- Cálculo de StringBuilder Tiempo transcurrido 8289 ms
- Cálculo LinqConcat Tiempo transcurrido 21512 ms
- Cálculo LinqJoin Tiempo transcurrido 19433 ms
- LinqAgg calculo Tiempo transcurrido 9230 ms
- Cálculo de Hex. Tiempo transcurrido 1976 ms.
Con:
int MANY_STRING_COUNT = 1000;
int MANY_STRING_LENGTH = 1024;
(El mismo byte cuenta como primera prueba pero en diferentes matrices)
- Tiempo de cálculo de BitConvertReplace transcurrido 25,680 ms
- Tiempo de cálculo de StringBuilder transcurrido 78,411 ms
- Cálculo LinqConcat Tiempo transcurrido 101.233 ms
- Cálculo de LinqJoin Tiempo transcurrido 99,311 ms
- LinqAgg cálculo del tiempo transcurrido 84,660 ms
- Cálculo de ToHex Tiempo transcurrido 18,221 ms
Con:
int MANY_STRING_COUNT = 2000;
int MANY_STRING_LENGTH = 20;
- BitConvertReplace cálculo Tiempo transcurrido 1347 ms
- Tiempo de cálculo de StringBuilder transcurrido 3234 ms
- Cálculo LinqConcat Tiempo transcurrido 5013 ms
- Cálculo LinqJoin Tiempo transcurrido 4826 ms
- LinqAgg cálculo Tiempo transcurrido 3589 ms
- Cálculo de ToHex Tiempo transcurrido 772 ms
Código de prueba que utilicé:
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();
}
También otra respuesta con un proceso similar , todavía no he comparado nuestros resultados.
Solo para agregar una respuesta más a la pila, hay una clase System.Runtime.Remoting.Metadata.W3cXsd2001.SoapHexBinary
que he usado que puede convertir bytes desde y hacia el hex:
string hex = new SoapHexBinary(bytes).ToString();
byte[] bytes = SoapHexBinary.Parse(hex).Value;
No estoy seguro de cómo se compara (referencia) con otras implementaciones, pero, en mi opinión, es bastante simple, especialmente para la conversión de hexadecimales a bytes.
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);
}