C# 将 byte[] 按十六进制值拆分为新的 byte[] 数组
C# Split byte[] by hexademimal value into new array of byte[]
我想从一个字节数组的 IP 数据包中获取数据,并将其拆分为以 0x47
开头的字节数组集合,即 mpeg-2 transport packets.
例如原始字节数组如下所示:
08 FF FF 47 FF FF FF 47 FF FF 47 FF 47 FF FF FF FF 47 FF FF
如何拆分 0x47
上的字节数组并保留分隔符 0x47
,使其看起来像这样?换句话说,以特定十六进制开头的字节数组数组?
[0] 08 FF FF
[1] 47 FF FF FF
[2] 47 FF FF
[3] 47 FF
[4] 47 FF FF FF FF
[5] 47 FF FF
有几种方法可以做到这一点,最简单的方法是只使用 .Split() 并替换要拆分的值。
string[] values = packet.Split("47");
for(int i = 0; i < values.Length; i++)
{
Console.WriteLine("[{0}] 47 {1}", i, values[i]);
// C# 6+ way: Console.WriteLine($"[{i}] 47 {values[i]}");
}
当然,您始终可以使用正则表达式,但我的 Regex 技能非常有限,我认为我个人无法为此构建有效的正则表达式。
也许对你来说有点太老套了,但应该没问题:
string ins = "08 FF FF 47 FF FF FF 47 FF FF 47 FF 47 FF FF FF FF 47 FF FF ";
string[] splits = ins.Split(new string[] { "47" }, StringSplitOptions.None);
for (int i = 0; i < splits.Length; i++) {
splits[i] = "47 " + splits[i];
}
编辑:类似于我猜的已经存在的答案。
可能的解决方案:
byte[] source = // ...
string packet = String.Join(" ", source.Select(b => b.ToString("X2")));
// chunks is of type IEnumerable<IEnumerable<byte>>
var chunks = Regex.Split(packet, @"(?=47)")
.Select(c =>
c.Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => Convert.ToByte(x, 16)));
您可以轻松实现所需的拆分器:
public static IEnumerable<Byte[]> SplitByteArray(IEnumerable<Byte> source, byte marker) {
if (null == source)
throw new ArgumentNullException("source");
List<byte> current = new List<byte>();
foreach (byte b in source) {
if (b == marker) {
if (current.Count > 0)
yield return current.ToArray();
current.Clear();
}
current.Add(b);
}
if (current.Count > 0)
yield return current.ToArray();
}
并使用它:
String source = "08 FF FF 47 FF FF FF 47 FF FF 47 FF 47 FF FF FF FF 47 FF FF";
// the data
Byte[] data = source
.Split(' ')
.Select(x => Convert.ToByte(x, 16))
.ToArray();
// splitted
Byte[][] result = SplitByteArray(data, 0x47).ToArray();
// data splitted has been represented for testing
String report = String.Join(Environment.NewLine,
result.Select(line => String.Join(" ", line.Select(x => x.ToString("X2")))));
// 08 FF FF
// 47 FF FF FF
// 47 FF FF
// 47 FF
// 47 FF FF FF FF
// 47 FF FF
Console.Write(report);
我想从一个字节数组的 IP 数据包中获取数据,并将其拆分为以 0x47
开头的字节数组集合,即 mpeg-2 transport packets.
例如原始字节数组如下所示:
08 FF FF 47 FF FF FF 47 FF FF 47 FF 47 FF FF FF FF 47 FF FF
如何拆分 0x47
上的字节数组并保留分隔符 0x47
,使其看起来像这样?换句话说,以特定十六进制开头的字节数组数组?
[0] 08 FF FF
[1] 47 FF FF FF
[2] 47 FF FF
[3] 47 FF
[4] 47 FF FF FF FF
[5] 47 FF FF
有几种方法可以做到这一点,最简单的方法是只使用 .Split() 并替换要拆分的值。
string[] values = packet.Split("47");
for(int i = 0; i < values.Length; i++)
{
Console.WriteLine("[{0}] 47 {1}", i, values[i]);
// C# 6+ way: Console.WriteLine($"[{i}] 47 {values[i]}");
}
当然,您始终可以使用正则表达式,但我的 Regex 技能非常有限,我认为我个人无法为此构建有效的正则表达式。
也许对你来说有点太老套了,但应该没问题:
string ins = "08 FF FF 47 FF FF FF 47 FF FF 47 FF 47 FF FF FF FF 47 FF FF ";
string[] splits = ins.Split(new string[] { "47" }, StringSplitOptions.None);
for (int i = 0; i < splits.Length; i++) {
splits[i] = "47 " + splits[i];
}
编辑:类似于我猜的已经存在的答案。
可能的解决方案:
byte[] source = // ...
string packet = String.Join(" ", source.Select(b => b.ToString("X2")));
// chunks is of type IEnumerable<IEnumerable<byte>>
var chunks = Regex.Split(packet, @"(?=47)")
.Select(c =>
c.Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => Convert.ToByte(x, 16)));
您可以轻松实现所需的拆分器:
public static IEnumerable<Byte[]> SplitByteArray(IEnumerable<Byte> source, byte marker) {
if (null == source)
throw new ArgumentNullException("source");
List<byte> current = new List<byte>();
foreach (byte b in source) {
if (b == marker) {
if (current.Count > 0)
yield return current.ToArray();
current.Clear();
}
current.Add(b);
}
if (current.Count > 0)
yield return current.ToArray();
}
并使用它:
String source = "08 FF FF 47 FF FF FF 47 FF FF 47 FF 47 FF FF FF FF 47 FF FF";
// the data
Byte[] data = source
.Split(' ')
.Select(x => Convert.ToByte(x, 16))
.ToArray();
// splitted
Byte[][] result = SplitByteArray(data, 0x47).ToArray();
// data splitted has been represented for testing
String report = String.Join(Environment.NewLine,
result.Select(line => String.Join(" ", line.Select(x => x.ToString("X2")))));
// 08 FF FF
// 47 FF FF FF
// 47 FF FF
// 47 FF
// 47 FF FF FF FF
// 47 FF FF
Console.Write(report);