Pergunta

Eu posso dizer que eu não sei o que estou pedindo ajuda, porque eu não sei o formato, mas eu tenho uma imagem.

Eu tenho uma matriz byte [], como faço para convertê-lo para esse formato abaixo (em certo)?

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

A sua não é simples ascii.

Foi útil?

Solução

Use b.ToString("x2") para formatar um valor de byte em uma cadeia hexadecimal de dois caracteres.

Para a exibição ASCII, verifique se as corresponde valor a um personagem de impressão regular e convertê-lo se:

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

ou mais curto:

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

Para fazê-lo em um array:

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

Outras dicas

Parece que você gostaria de ter uma matriz de bytes, e convertê-lo ao texto (substituindo caracteres fora de um determinado intervalo com "." 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();
}

ou como um método de extensão LINQy (dentro de uma classe de extensão estática):

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

(Você poderia chamar isso como string printable = byteArray.ToPrintableString();)

Esta poderia ser qualquer número de codificações ... tente este script de teste teste para ver qual deles imprimir:

Bl8s

Aqui está o 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);
}

[editar de 2018:] Re-escreveu a função a partir do zero para tornar o código muito mais eficiente e corrigir alguns outros problemas. Agora também é possível especificar, opcionalmente, um deslocamento inicial e número de bytes (a partir daí) para exibição.


Se você quer que o display inteiro memória, incluindo o número de deslocamento, e apresenta esquerda e direita, você pode fazê-lo como este: (largura 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();
}

O código usa os seguintes ajudantes para determinar quais os personagens devem ser mostrados como 'pontos' em parte da mão direita.

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

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

Saída dos olhares função acima assim (largura dos caracteres é de 138 colunas, de rolagem para a direita para ver a parte "legível"):

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

Tente: Encoding.Default.GetBytes

Se isso não funcionar, existem diferentes tipos que você pode especificar (UTF-8, ASCII ...)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top