c# 语言 List data = new List<>(){255,2,2,255,4,1,3,10,255,4,2,5,10,255,3,12,34,46}
多条指令的数据粘合成了一组数据,根据条件完成切分出单条指令数据和判断指令数据正误的算法:
(1) 每条指令以255开头
(2)指令第二位的数值表示从此位开始到指令最后一位的数据个数
(3)指令最后一位的值是校验值,等于从第二位开始到最后一位之前各个数值的和
需要实现的方法:
List<List> SplitCommand (List dnta)//切分出单条指令的数
bool CheckCommand (List command) //判断单条指令的数据正误
题注指令拆分只是按照1还是1,2结合?下面的话按照1,只要255开头就作为一条指令
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp1
{
public class Program
{
public static void Main()
{
List<int> data = new List<int>() { 255, 2, 2, 255, 4, 1, 3, 10, 255, 4, 2, 5, 10, 255, 3, 12, 34, 46 };
List<List<int>> commands = SplitCommand(data);
foreach (List<int> command in commands)
{
Console.WriteLine("指令{0}{1}", string.Join(",", command), CheckCommand(command) ? "正确" : "错误");
}
Console.ReadKey();
}
public static List<List<int>> SplitCommand(List<int> data)
{
var s = string.Join(",", data);
var arr = s.Split(new string[] { "255," }, StringSplitOptions.RemoveEmptyEntries);
var list= arr.Select(i => i.Split(new string[] { ","},StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList()).ToList();
foreach (var l in list) l.Insert(0, 255);
return list;
}
public static bool CheckCommand(List<int> command)
{
if (command.Count < 3 || command[1] != command.Count - 1 || command.Last() != command.GetRange(1, command.Count - 2).Sum()) return false;
return true;
}
}
}
额,我不打算按你的要求写那个函数。我只是来展示如何处理这种数据
环境:net6 控制台
nuget:system.io.pipelines
using System.IO.Pipelines;
using System.Buffers;
using System;
//为了测试,我故意把题中255,4,2,5,10 修改成255,4,2,5,11以满足校验条件
List<Byte> data = new List<byte>{255,2,2,255,4,1,3,10,255,4,2,5,11,255,3,12,34,46};
MemoryStream memoryStream=new MemoryStream(data.ToArray());
var pipereader=PipeReader.Create(memoryStream);
while(true)
{
var r=await pipereader.ReadAsync();
var buffer=r.Buffer;
while(TryPrasePackage(out var package,ref buffer))
{
Console.WriteLine(string.Join(',',package.Select(p=>(int)p)) );
}
pipereader.AdvanceTo(buffer.Start,buffer.End);
}
Console.ReadLine();
bool TryPrasePackage(out byte[] package,ref ReadOnlySequence<byte> buffer)
{
bool res=false;
package=null;
SequenceReader<byte> reader=new SequenceReader<byte>(buffer);
while(!reader.End)
{
if( reader.TryAdvanceTo(0xff,true))
{
var start=reader.Position.GetInteger()-buffer.Start.GetInteger()-1;
if( reader.TryRead(out var datacount))
{
byte[] databuffer=new byte[datacount];
databuffer[0]=datacount;
Span<byte> data=databuffer.AsSpan(1);
if(reader.TryCopyTo(data))
{
reader.Advance(datacount-1);
if(checksum(databuffer))
{
var end=reader.Position;
package=buffer.Slice(start,end).ToArray();
buffer=buffer.Slice(reader.Position);
return true;
}
}
}
}
}
return res;
}
bool checksum(byte[] data)
{
int sum=0;
for(var i=0;i<data.Length-1;i++)
{
sum +=data[i];
sum=sum&0xff;
}
return sum==data[data.Length-1];
}
最后结果:
255,2,2
255,4,2,5,11
有两条满足条件
以下是 c# 语言的代码实现:
using System;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
List<int> data = new List<int>() { 255, 2, 2, 255, 4, 1, 3, 10, 255, 4, 2, 5, 10, 255, 3, 12, 34, 46 };
List<List<int>> commands = SplitCommand(data);
foreach (List<int> command in commands)
{
if (CheckCommand(command))
{
Console.WriteLine("Command {0} is valid", command[0]);
}
else
{
Console.WriteLine("Command {0} is not valid", command[0]);
}
}
}
public static List<List<int>> SplitCommand(List<int> data)
{
List<List<int>> commands = new List<List<int>>();
for (int i = 0; i < data.Count; i++)
{
if (data[i] == 255 && data[i + 1] > 0 && data.Count >= i + data[i + 1] + 2)
{
List<int> command = new List<int>(data.GetRange(i, data[i + 1] + 2));
commands.Add(command);
i += data[i + 1] + 1;
}
}
return commands;
}
public static bool CheckCommand(List<int> command)
{
if (command.Count < 3 || command[0] != 255 || command[command.Count - 1] != (command.GetRange(1, command.Count - 2).Sum() & 0xFF))
{
return false;
}
return true;
}
}
在这个代码中,我们首先定义了一个包含多条指令数据的 List 对象 data,然后调用 SplitCommand 方法将多条指令数据切分成单条指令数据,再调用 CheckCommand 方法判断单条指令数据是否正确。
SplitCommand 方法首先创建一个空的 List 对象 commands,表示切分出来的多条指令数据。然后,我们使用 for 循环遍历 data 列表中的元素。当我们检测到一个以 255 开头的指令数据时,我们就可以切分出一条指令数据,并将其添加到 commands 列表中。循环变量 i 需要跳过刚才切分出来的指令数据的位置,从下一个指令数据开始继续遍历 data 列表。
CheckCommand 方法判断单条指令数据是否正确,根据规则,我们需要检查指令长度和校验和是否正确。如果指令数据长度小于 3,或者指令数据校验和不等于指令数据中第二位到倒数第二位的数值之和,则指令数据不正确,返回 false。否则,返回 true。
需要注意的是,该程序并未进行异常处理、容错等处理,实际应用时需要根据具体需求增加相关的代码。
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!