Pregunta

Puedo decir que no sé qué estoy pidiendo ayuda, porque no sé el formato, pero tengo una foto.

Tengo una matriz de bytes [], ¿cómo la convierto a ese formato a continuación (a la derecha)?

texto alternativo http://img512.imageshack.us/img512/3548/48667724 .jpg

No es simple ascii.

¿Fue útil?

Solución

Use b.ToString (" x2 ") para formatear un valor de byte en una cadena hexadecimal de dos caracteres.

Para la pantalla ASCII, compruebe si el valor corresponde a un carácter de impresión normal y conviértalo si es:

if (b >= 32 && b <= 127) {
   c = (char)b;
} else {
   c = '.';
}

O más corto:

c = b >= 32 && b <= 127 ? (char)b : '.';

Para hacerlo en una matriz:

StringBuilder builder = new StringBuilder();
foreach (b in theArray) {
   builder.Append(b >= 32 && b <= 127 ? (char)b : '.');
}
string result = builder.ToString();

Otros consejos

Parece que te gustaría tomar una matriz de bytes y convertirla en texto (reemplazando los caracteres fuera de un cierto rango con " . " s)

static public string ConvertFromBytes(byte[] input)
{
    StringBuilder output = new StringBuilder(input.Length);

    foreach (byte b in input)
    {
        // Printable chars are from 0x20 (space) to 0x7E (~)
        if (b >= 0x20 && b <= 0x7E)
        {
            output.Append((char)b);
        }
        else
        {
            // This isn't a text char, so use a placehold char instead
            output.Append(".");
        }
    }

    return output.ToString();
}

o como un método de extensión LINQy (dentro de una clase de extensión estática):

static public string ToPrintableString(this byte[] bytes)
{
    return Encoding.ASCII.GetString
           (
              bytes.Select(x => x < 0x20 || x > 0x7E ? (byte)'.' : x)
                   .ToArray()
           );
}

(Podrías llamarlo como string printable = byteArray.ToPrintableString (); )

Esto podría ser cualquier número de codificaciones ... pruebe esta secuencia de comandos de prueba para ver cuál de ellas se imprime:

Bl8s

Aquí está el script:

byte[] b = new byte[] {0x42, 0x6C, 0x38, 0x73 };
foreach (EncodingInfo ei in Encoding.GetEncodings())
{
     Console.WriteLine("{0} - {1}", ei.GetEncoding().GetString(b), ei.Name);
}

[edit 2018:] Reescribió la función desde cero para hacer que el código sea mucho más eficiente y solucionar otros problemas. Ahora también puede especificar opcionalmente un desplazamiento de inicio y el número de bytes (a partir de allí) para mostrar.


Si desea que se muestre toda la memoria, incluido el número de desplazamiento, y las pantallas izquierda y derecha, puede hacerlo de la siguiente manera: (ancho de 32 bytes)

/// <summary> Returns a String where the specified bytes are formatted in a
/// 3-section debugger-style aligned memory display, 32-bytes per line </summary>
public static unsafe String MemoryDisplay(byte[] mem, int i_start = 0, int c = -1)
{
    if (mem == null)
        throw new ArgumentNullException();
    if (i_start < 0)
        throw new IndexOutOfRangeException();
    if (c == -1)
        c = mem.Length - i_start;
    else if (c < 0)
        throw new ArgumentException();
    if (c == 0)
        return String.Empty;

    char* pch = stackalloc Char[32];       // for building right side at the same time
    var sb = new StringBuilder((c / 32 + 1) * 140);            // exact pre-allocation

    c += i_start;
    for (int i = i_start & ~0x1F; i < c;)
    {
        sb.Append(i.ToString("x8"));
        sb.Append(' ');

        do
        {
            if (i < i_start || i >= c)          // non-requested area, or past the end
            {
                sb.Append("   ");   
                pch[i & 0x1F] = ' ';
            }
            else
            {
                var b = mem[i];
                sb.Append(b.ToString("x2") + " ");
                pch[i & 0x1F] = non_monospace(b) ? '.' : (Char)b;
            }
        }
        while ((++i & 0x1F) != 0);

        sb.Append(' ');
        sb.AppendLine(new String(pch, 0, 32));
    }
    return sb.ToString();
}

El código utiliza los siguientes ayudantes para determinar qué caracteres deben mostrarse como 'puntos' en la parte derecha.

static readonly ulong[] _nmb =
{
    0x00000000ffffe7ffUL,
    0x8000000000000000UL,
    0x00002000ffffffffUL,
    0x0000000000000000UL,
};

static bool non_monospace(byte b) => (_nmb[b >> 6] & 1UL << b) != 0;

La salida de la función anterior tiene este aspecto (el ancho de los caracteres es de 138 columnas, desplácese hacia la derecha para ver la parte " legible por el hombre "):

00000000 47 49 46 38 39 61 0f 00 0f 00 91 ff 00 00 00 00 c0 c0 c0 ff ff 00 00 00 00 21 f9 04 01 00 00 01 GIF89a...................!......
00000020 00 2c 00 00 00 00 0f 00 0f 00 00 02 2c 8c 0d 99 c7 91 02 e1 62 20 5a 79 ea bd 00 6d 89 69 8a f8 .,..........,.......b Zy...m.i..
00000040 08 e5 a7 99 e9 17 9d ac 24 a2 21 68 89 1e ac b4 d9 db 51 ab da c8 8c 1a 05 00 3b                ........$.!h......Q.......;

Prueba: Encoding.Default.GetBytes

Si eso no funciona, hay diferentes tipos que puede especificar (UTF-8, ASCII ...)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top