sharppcap: '.'使用 printHex() 方法使用字符而不是空格
sharppcap: '.' characters instead of spaces with printHex() method
我使用 SharpPcap 库成功地解析了“.pcap”文件。
目标是从 TCP/HTTP 数据包中检索 XML 数据。为此,我使用了以下代码(删除了空检查以使其更具可读性):
Packet packet = Packet.ParsePacket(eventArguments.Packet.LinkLayerType, eventArguments.Packet.Data);
EthernetPacket ethernetPacket = ((EthernetPacket)packet);
IpPacket ipPacket = (IpPacket)packet.Extract(typeof(IpPacket));
TcpPacket tcpPacket = (TcpPacket)packet.Extract(typeof(TcpPacket));
string rawData = tcpPacket.PrintHex();
移动,除了十六进制值和初始行,我能够从 rawData 变量中提取 XML 数据,以及意外的副作用.
.PrintHex()
returns '.' 而不是空格字符:
而不是:
<xml>Only text here</xml>
我得到这个:
<xml>Only.text.here</xml>
我没有做任何奇怪的替换或字节转换。以上行为正是 .PrintHex()
returns.
- 这是否是预期的结果?
- 更重要的是...如何修复或预防这种情况? (请记住,无法区分有效的“.”和转换后的“.”)
库版本:
.NET Framework: > 4.5.2
Pcapsharp: 4.2.0
尝试使用 ToString()
方法的覆盖,它似乎完全符合您的期望。
如果这不起作用,您可以选择从 Packet
实现 public string PrintHex()
。如果你看一下反编译代码,这就是你的问题:
if ((int) bytes[index - 1] < 33 || (int) bytes[index - 1] > 126)
str2 += ".";
else
str2 += Encoding.ASCII.GetString(new byte[1]
{
bytes[index - 1]
});
只有dec
编码在33到126之间的字符会保持不变,其余的会被替换为.
(包括space
也就是32http://www.asciitable.com/) .由于 BytesHighPerformance.Bytes
是 public,您可以很容易地按照这些思路编写自己的扩展方法。
TcpPacket tcpPacket = (TcpPacket)packet.Extract(typeof(TcpPacket));
string rawData = tcpPacket.CustomPrintHex();
public static class Extensions
{
public static string CustomPrintHex(this TcpPacket self)
{
byte[] bytes = self.BytesHighPerformance.Bytes;
// copy / paste of `PrintHex()` with your custom conversion
}
}
这可能对其他人有帮助,所以我发布了我的最终解决方案(基于已接受的答案)。
附加功能:
- 利用字符串生成器提高性能
- 包括换行符
public class TcpPacketCustom: TcpPacket
{
public static int AsciiRangeMin { get; } = 32;
public static int AsciiRangeMax { get; } = 126;
public static HashSet<int> AdditionalAsciiCodes { get; } = new HashSet<int> { 10, 13 }; //ascii codes of carriage and new line
public TcpPacketCustom(ByteArraySegment byteArraySegment) : base(byteArraySegment) { }
public new string PrintHex()
{
StringBuilder stringBuilder = new StringBuilder();
foreach (byte b in this.BytesHighPerformance.Bytes)
{
int asciiCode = (int)b;
if ( ((asciiCode < AsciiRangeMin) || (asciiCode > AsciiRangeMax)) && !AdditionalAsciiCodes.Contains(asciiCode) )
{
stringBuilder.Append(".");
}
else
{
stringBuilder.Append(Encoding.ASCII.GetString(new byte[1] { b }));
}
}
return stringBuilder.ToString();
}
}
我使用 SharpPcap 库成功地解析了“.pcap”文件。
目标是从 TCP/HTTP 数据包中检索 XML 数据。为此,我使用了以下代码(删除了空检查以使其更具可读性):
Packet packet = Packet.ParsePacket(eventArguments.Packet.LinkLayerType, eventArguments.Packet.Data);
EthernetPacket ethernetPacket = ((EthernetPacket)packet);
IpPacket ipPacket = (IpPacket)packet.Extract(typeof(IpPacket));
TcpPacket tcpPacket = (TcpPacket)packet.Extract(typeof(TcpPacket));
string rawData = tcpPacket.PrintHex();
移动,除了十六进制值和初始行,我能够从 rawData 变量中提取 XML 数据,以及意外的副作用.
.PrintHex()
returns '.' 而不是空格字符:
而不是:
<xml>Only text here</xml>
我得到这个:
<xml>Only.text.here</xml>
我没有做任何奇怪的替换或字节转换。以上行为正是 .PrintHex()
returns.
- 这是否是预期的结果?
- 更重要的是...如何修复或预防这种情况? (请记住,无法区分有效的“.”和转换后的“.”)
库版本:
.NET Framework: > 4.5.2
Pcapsharp: 4.2.0
尝试使用 ToString()
方法的覆盖,它似乎完全符合您的期望。
如果这不起作用,您可以选择从 Packet
实现 public string PrintHex()
。如果你看一下反编译代码,这就是你的问题:
if ((int) bytes[index - 1] < 33 || (int) bytes[index - 1] > 126)
str2 += ".";
else
str2 += Encoding.ASCII.GetString(new byte[1]
{
bytes[index - 1]
});
只有dec
编码在33到126之间的字符会保持不变,其余的会被替换为.
(包括space
也就是32http://www.asciitable.com/) .由于 BytesHighPerformance.Bytes
是 public,您可以很容易地按照这些思路编写自己的扩展方法。
TcpPacket tcpPacket = (TcpPacket)packet.Extract(typeof(TcpPacket));
string rawData = tcpPacket.CustomPrintHex();
public static class Extensions
{
public static string CustomPrintHex(this TcpPacket self)
{
byte[] bytes = self.BytesHighPerformance.Bytes;
// copy / paste of `PrintHex()` with your custom conversion
}
}
这可能对其他人有帮助,所以我发布了我的最终解决方案(基于已接受的答案)。
附加功能:
- 利用字符串生成器提高性能
- 包括换行符
public class TcpPacketCustom: TcpPacket
{
public static int AsciiRangeMin { get; } = 32;
public static int AsciiRangeMax { get; } = 126;
public static HashSet<int> AdditionalAsciiCodes { get; } = new HashSet<int> { 10, 13 }; //ascii codes of carriage and new line
public TcpPacketCustom(ByteArraySegment byteArraySegment) : base(byteArraySegment) { }
public new string PrintHex()
{
StringBuilder stringBuilder = new StringBuilder();
foreach (byte b in this.BytesHighPerformance.Bytes)
{
int asciiCode = (int)b;
if ( ((asciiCode < AsciiRangeMin) || (asciiCode > AsciiRangeMax)) && !AdditionalAsciiCodes.Contains(asciiCode) )
{
stringBuilder.Append(".");
}
else
{
stringBuilder.Append(Encoding.ASCII.GetString(new byte[1] { b }));
}
}
return stringBuilder.ToString();
}
}