Question

Je peux dire que je ne sais pas ce que je demande de l'aide, car je ne connais pas le format, mais j'ai une photo.

J'ai un tableau d'octets [], comment puis-je le convertir dans ce format ci-dessous (à droite)?

texte de remplacement http://img512.imageshack.us/img512/3548/48667724 .jpg

Ce n'est pas évident.

Était-ce utile?

La solution

Utilisez b.ToString ("x2") pour formater une valeur d'octet en une chaîne hexadécimale à deux caractères.

Pour l’affichage ASCII, vérifiez si la valeur correspond à un caractère imprimable normal et convertissez-la si elle est:

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

Ou plus court:

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

Pour le faire sur un tableau:

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

Autres conseils

Il semble que vous souhaitiez convertir un tableau d'octets en texte (en remplaçant des caractères situés en dehors d'une plage donnée par des "" . ")

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 en tant que méthode d'extension LINQy (à l'intérieur d'une classe d'extension statique):

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

(Vous pouvez appeler cela comme chaîne imprimable = byteArray.ToPrintableString (); )

Il peut s'agir d'un nombre quelconque d'encodages ... essayez ce script de test pour savoir lequel d'entre eux s'imprime:

Bl8s

Voici le 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:] Réécrivez la fonction à partir de zéro pour rendre le code beaucoup plus efficace et résoudre certains autres problèmes. Vous pouvez désormais également spécifier un décalage de départ et un nombre d'octets (à partir de là) à afficher.

Si vous souhaitez afficher la totalité de la mémoire, y compris le numéro de décalage et les affichages gauche et droit, procédez comme suit: (largeur sur 32 octets)

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

Le code utilise les assistants suivants pour déterminer les caractères à afficher en tant que "points" dans la partie droite.

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

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

La sortie de la fonction ci-dessus ressemble à ceci (la largeur des caractères est de 138 colonnes, faites défiler vers la droite pour voir la "partie lisible par l'homme"):

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

Essayez: Encoding.Default.GetBytes

Si cela ne fonctionne pas, vous pouvez spécifier différents types (UTF-8, ASCII ...)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top