我想将数据包(byte [])转换为文本文件的十六进制转储视图,但它变得很乱。
这是一张照片。
我正在主byte[]
上循环,直到我达到16的mod(不包括0),但如果最后一行不是16的因子,那么最终将ASCII表示移到左边
我确实尝试了几种解决方案,但是非常不错,所以我认为这是一个盲点,并认为我可以使用一些帮助:)
此外,我可以使用一些帮助来检查该角色是否具有ascii表示,或者我应该用'。'替换它。
using (var sw = File.AppendText(Path))
{
sw.WriteLine("[Packet Logged at {0} with direction {1}] with length {2} and type {3}",
DateTime.Now.ToLongTimeString().Replace("PM", string.Empty).Replace("AM", string.Empty).Replace(" ", string.Empty),
ReadWrite.ReadString(Packet,Packet.Length-8,8) == "removed for privacy" ? "Server->Client" : "Client -> Server",
BitConverter.ToUInt16(Packet, 0), BitConverter.ToUInt16(Packet, 2));
for (int i = 0; i < Packet.Length; i++)
{
if (i%16 == 0 && i != 0)
{
}
else
{
sw.Write(Packet[i]);
}
}
}
答案 0 :(得分:4)
取自http://www.codeproject.com/Articles/36747/Quick-and-Dirty-HexDump-of-a-Byte-Array:
using System.Text;
namespace HexDump
{
class Utils
{
public static string HexDump(byte[] bytes, int bytesPerLine = 16)
{
if (bytes == null) return "<null>";
int bytesLength = bytes.Length;
char[] HexChars = "0123456789ABCDEF".ToCharArray();
int firstHexColumn =
8 // 8 characters for the address
+ 3; // 3 spaces
int firstCharColumn = firstHexColumn
+ bytesPerLine * 3 // - 2 digit for the hexadecimal value and 1 space
+ (bytesPerLine - 1) / 8 // - 1 extra space every 8 characters from the 9th
+ 2; // 2 spaces
int lineLength = firstCharColumn
+ bytesPerLine // - characters to show the ascii value
+ Environment.NewLine.Length; // Carriage return and line feed (should normally be 2)
char[] line = (new String(' ', lineLength - 2) + Environment.NewLine).ToCharArray();
int expectedLines = (bytesLength + bytesPerLine - 1) / bytesPerLine;
StringBuilder result = new StringBuilder(expectedLines * lineLength);
for (int i = 0; i < bytesLength; i += bytesPerLine)
{
line[0] = HexChars[(i >> 28) & 0xF];
line[1] = HexChars[(i >> 24) & 0xF];
line[2] = HexChars[(i >> 20) & 0xF];
line[3] = HexChars[(i >> 16) & 0xF];
line[4] = HexChars[(i >> 12) & 0xF];
line[5] = HexChars[(i >> 8) & 0xF];
line[6] = HexChars[(i >> 4) & 0xF];
line[7] = HexChars[(i >> 0) & 0xF];
int hexColumn = firstHexColumn;
int charColumn = firstCharColumn;
for (int j = 0; j < bytesPerLine; j++)
{
if (j > 0 && (j & 7) == 0) hexColumn++;
if (i + j >= bytesLength)
{
line[hexColumn] = ' ';
line[hexColumn + 1] = ' ';
line[charColumn] = ' ';
}
else
{
byte b = bytes[i + j];
line[hexColumn] = HexChars[(b >> 4) & 0xF];
line[hexColumn + 1] = HexChars[b & 0xF];
line[charColumn] = asciiSymbol( b );
}
hexColumn += 3;
charColumn++;
}
result.Append(line);
}
return result.ToString();
}
static char asciiSymbol( byte val )
{
if( val < 32 ) return '.'; // Non-printable ASCII
if( val < 127 ) return (char)val; // Normal ASCII
// Handle the hole in Latin-1
if( val == 127 ) return '.';
if( val < 0x90 ) return "€.‚ƒ„…†‡ˆ‰Š‹Œ.Ž."[ val & 0xF ];
if( val < 0xA0 ) return ".‘’“”•–—˜™š›œ.žŸ"[ val & 0xF ];
if( val == 0xAD ) return '.'; // Soft hyphen: this symbol is zero-width even in monospace fonts
return (char)val; // Normal Latin-1
}
}
}
答案 1 :(得分:0)
我写了这个转储二进制数据的解决方案:
public static class BinaryVisualiser
{
public static string FormatAsHex(ReadOnlySpan<byte> data)
{
byte ReplaceControlCharacterWithDot(byte character)
=> character < 31 || character >= 127 ? (byte)46 /* dot */ : character;
byte[] ReplaceControlCharactersWithDots(byte[] characters)
=> characters.Select(ReplaceControlCharacterWithDot).ToArray();
var result = new StringBuilder();
const int lineWidth = 16;
for (var pos = 0; pos < data.Length;)
{
var line = data.Slice(pos, Math.Min(lineWidth, data.Length - pos)).ToArray();
var asHex = string.Join(" ", line.Select(v => v.ToString("X2", CultureInfo.InvariantCulture)));
asHex += new string(' ', lineWidth * 3 - 1 - asHex.Length);
var asCharacters = Encoding.ASCII.GetString(ReplaceControlCharactersWithDots(line));
result.Append(FormattableString.Invariant($"{pos:X4} {asHex} {asCharacters}\n"));
pos += line.Length;
}
return result.ToString();
}
}
请注意,此实现利用了C#7.2中的Span
,并需要Microsoft的System.Memory
NuGet程序包。
输出格式如下:
0000 EF BB BF 48 65 6C 6C 6F 2C 20 53 74 61 63 6B 20 ...Hello, Stack
0010 4F 76 65 72 66 6C 6F 77 21 Overflow!
更新:可配置的字节宽度。
public static string FormatAsHex(ReadOnlySpan<byte> data, int lineWidth = 16, int byteWidth = 1)
{
byte ReplaceControlCharacterWithDot(byte character) => character < 31 || character >= 127 ? (byte)46 /* dot */ : character;
byte[] ReplaceControlCharactersWithDots(byte[] characters) => characters.Select(ReplaceControlCharacterWithDot).ToArray();
IEnumerable<BigInteger> Chunk(IReadOnlyList<byte> source, int size) => source.Select((item, index) => source.Skip(size * index).Take(size).ToArray()).TakeWhile(bucket => bucket.Any()).Select(e => new BigInteger(e));
var result = new StringBuilder();
for(var pos = 0; pos < data.Length;)
{
var line = data.Slice(pos, Math.Min(lineWidth * byteWidth, data.Length - pos)).ToArray();
var asHex = string.Join(" ", Chunk(line, byteWidth).Select(v => v.ToString("X" + byteWidth * 2, CultureInfo.InvariantCulture)));
asHex += new string(' ', lineWidth * (byteWidth * 2 + 1) - 1 - asHex.Length);
var asCharacters = Encoding.ASCII.GetString(ReplaceControlCharactersWithDots(line));
result.Append(Invariant($"{pos:X4} {asHex} {asCharacters}\n"));
pos += line.Length;
}
return result.ToString();
}
允许(编码为big-endian UTF-16):
0000 4800 6500 6C00 6C00 6F00 2C00 .H.e.l.l.o.,
000C 2000 5300 7400 6100 6300 6B00 . .S.t.a.c.k
0018 2000 4F00 7600 6500 7200 6600 . .O.v.e.r.f
0024 6C00 6F00 7700 .l.o.w
答案 2 :(得分:-1)
对齐对于末端扇区无关紧要,至少不是出于性能原因。起始扇区的对齐会影响分区;最后一个扇区的对齐只影响分区的最后几个扇区,如果有的话。所以扇区是从 0 开始的数字,fdisk 建议您磁盘上具有上述结果的最后一个扇区。
希望这对您有所帮助。