给出字符串数组的这种结构
string[] content = {"0x1", "5", "0x8", "7", "0x66"};
如何获取content
等效字节数组表示形式?我知道如何转换“ 5”,“ 7”和“ 0x66”,但是我正在努力构建数组中半字节0x1
,0x8
的整个字节数组表示形式...基本上我不知道如何将“ 0x1"
,"5"
,"0x8"
合并为两个字节...
其他信息:字符串数组的序列仅包含字节或半字节数据。前缀“ 0x”和一个数字应被视为半字节,无前缀的数字应被视为字节,具有两个数字的十六进制字符串应被视为字节。
答案 0 :(得分:2)
如果所有项目均假定为十六进制,则 Linq 和Convert
就足够了:
string[] content = {"0x1", "5", "0x8", "7", "0x66"};
byte[] result = content
.Select(item => Convert.ToByte(item, 16))
.ToArray();
如果"5"
和"7"
应该是十进制 (因为它们不要从0x
开始),我们有添加条件:
byte[] result = content
.Select(item => Convert.ToByte(item, item.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
? 16
: 10))
.ToArray();
编辑:如果我们想结合蚕食,让我们为其提取一种方法:
private static byte[] Nibbles(IEnumerable<string> data) {
List<byte> list = new List<byte>();
bool head = true;
foreach (var item in data) {
byte value = item.StartsWith("0x", StringComparison.OrdinalIgnoreCase)
? Convert.ToByte(item, 16)
: Convert.ToByte(item, 10);
// Do we have a nibble?
// 0xDigit (Length = 3) or Digit (Length = 1) are supposed to be nibble
if (item.Length == 3 || item.Length == 1) { // Nibble
if (head) // Head
list.Add(Convert.ToByte(item, 16));
else // Tail
list[list.Count - 1] = (byte)(list[list.Count - 1] * 16 + value);
head = !head;
}
else { // Entire byte
head = true;
list.Add(value);
}
}
return list.ToArray();
}
...
string[] content = { "0x1", "5", "0x8", "7", "0x66" };
Console.Write(string.Join(", ", Nibbles(content)
.Select(item => $"0x{item:x2}").ToArray()));
结果:
// "0x1", "5" are combined into 0x15
// "0x8", "7" are combined into 0x87
// "0x66" is treated as a byte 0x66
0x15, 0x87, 0x66
答案 1 :(得分:0)
您可以使用Zip
方法将源与具有相同源偏移量1的源合并。
string[] source = { "0x1", "5", "0x8", "7", "0x66" };
var offsetSource = source.Skip(1).Concat(new string[] { "" });
var bytes = source
.Zip(offsetSource, (s1, s2) => s1 + s2)
.Where(s => s.Length == 4 && s.StartsWith("0x"))
.Select(s => Convert.ToByte(s, 16))
.ToArray();
Console.WriteLine(String.Join(", ", bytes)); // Output: 21, 135, 102