Domanda

Posso dire di non sapere cosa sto chiedendo aiuto, perché non conosco il formato, ma ho una foto.

Ho un array byte [], come posso convertirlo in quel formato qui sotto (a destra)?

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

Non è assolutamente ascii.

È stato utile?

Soluzione

Utilizza b.ToString (" x2 ") per formattare un valore di byte in una stringa esadecimale di due caratteri.

Per la visualizzazione ASCII, controlla se il valore corrisponde a un normale carattere stampabile e convertilo se è:

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

O più breve:

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

Per farlo su un array:

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

Altri suggerimenti

Sembra che tu voglia prendere una matrice di byte e convertirla in testo (sostituendo i caratteri al di fuori di un certo intervallo 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 come metodo di estensione LINQy (all'interno di una classe di estensione statica):

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

(Puoi chiamarlo come string printable = byteArray.ToPrintableString (); )

Potrebbe trattarsi di un numero qualsiasi di codifiche ... prova questo script di test per vedere quali di esse stampano:

Bl8s

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

[modifica 2018:] ho riscritto la funzione da zero per rendere il codice molto più efficiente e risolvere alcuni altri problemi. Ora puoi anche facoltativamente specificare un offset iniziale e il numero di byte (a partire da lì) da visualizzare.


Se si desidera visualizzare l'intera memoria, incluso il numero di offset e i display sinistro e destro, è possibile farlo in questo modo: (larghezza di 32 byte)

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

Il codice utilizza i seguenti helper per determinare quali caratteri devono essere mostrati come 'punti' nella parte di destra.

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

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

L'output della funzione sopra è simile a questo (la larghezza del carattere è di 138 colonne, scorrere verso destra per vedere la parte " leggibile dall'utente "):

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

Prova: Encoding.Default.GetBytes

Se il problema persiste, è possibile specificare diversi tipi (UTF-8, ASCII ...)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top