我可以说我不知道我在寻求帮助,因为我不知道格式,但我有一张照片。
我有一个byte []数组,如何将其转换为下面的格式(右图)?
alt text http://img512.imageshack.us/img512/3548/48667724.jpg
它不是简单的ascii。
答案 0 :(得分:6)
听起来你想要一个字节数组,并将其转换为文本(用“.
”替换某个范围之外的字符)
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();
)
答案 1 :(得分:5)
使用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();
答案 2 :(得分:1)
这可以是任意数量的编码...尝试这个测试测试脚本,看看哪些打印出来:
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);
}
答案 3 :(得分:1)
[编辑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.......;
答案 4 :(得分:0)
尝试:Encoding.Default.GetBytes
如果不起作用,可以指定不同的类型(UTF-8,ASCII ...)