Как преобразовать byte [] в этот текстовый формат?

StackOverflow https://stackoverflow.com/questions/812716

  •  03-07-2019
  •  | 
  •  

Вопрос

Я могу сказать, что не знаю, о чем прошу помощи, потому что не знаю формат, но у меня есть картинка.

У меня есть массив byte [], как мне преобразовать его в этот формат ниже (справа)?

альтернативный текст http://img512.imageshack.us/img512/3548/48667724 .jpg

Это не просто ascii.

Это было полезно?

Решение

Используйте b.ToString (" x2 ") , чтобы отформатировать значение байта в шестнадцатеричную строку из двух символов.

Для отображения ASCII проверьте, соответствует ли значение обычному печатному символу, и преобразуйте его, если оно есть:

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

Или короче:

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

Чтобы сделать это в массиве:

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

Другие советы

Звучит так, будто вы хотите взять массив байтов и преобразовать его в текст (заменив символы вне определенного диапазона на " . " 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();
}

или как метод расширения LINQy (внутри статического класса расширения):

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

(Вы можете назвать это как string printable = byteArray.ToPrintableString (); )

Это может быть любое количество кодировок ... попробуйте этот тестовый тестовый сценарий, чтобы увидеть, какие из них выводятся на печать:

Bl8s

Вот сценарий:

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:] Переписал функцию с нуля, чтобы сделать код намного более эффективным и исправить некоторые другие проблемы. Теперь вы также можете указать начальное смещение и количество байтов (начиная с него) для отображения.

<Ч>

Если вы хотите, чтобы весь дисплей памяти, включая номер смещения, а также левый и правый дисплеи, вы можете сделать это следующим образом: (ширина 32 байта)

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

Код использует следующие помощники, чтобы определить, какие символы должны отображаться в виде точек в правой части.

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

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

Вывод вышеупомянутой функции выглядит следующим образом (ширина символа составляет 138 столбцов, прокрутите вправо, чтобы увидеть «читаемую человеком» часть):

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

Попробуйте: Encoding.Default.GetBytes

Если это не сработает, вы можете указать разные типы (UTF-8, ASCII ...)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top