using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; using System.Text; namespace MultiWheelC.TrajectoryPlanning.PathSmoothing.Comparison; /// 为重复执行结果生成与进程无关的稳定几何 SHA-256 摘要。 public static class StableGeometryDigest { /// 计算正式平滑结果的状态、方法、分段和路径位模式摘要。 public static string Compute(PathSmoothingResult result) { if (result == null) throw new ArgumentNullException(nameof(result)); return Compute(result.Status, result.Method, result.Path, result.Segments); } /// 计算任意已分析路径的稳定摘要。 public static string Compute( PathSmoothingStatus status, SmoothingMethod? method, IReadOnlyList path, IReadOnlyList segments) { using (var stream = new MemoryStream()) { WriteInt32(stream, 1); WriteInt32(stream, (int)status); WriteBoolean(stream, method.HasValue); if (method.HasValue) WriteInt32(stream, (int)method.Value); WriteInt32(stream, path == null ? 0 : path.Count); if (path != null) { for (int index = 0; index < path.Count; index++) WritePoint(stream, path[index]); } WriteInt32(stream, segments == null ? 0 : segments.Count); if (segments != null) { for (int index = 0; index < segments.Count; index++) WriteSegment(stream, segments[index]); } using (SHA256 sha256 = SHA256.Create()) { byte[] hash = sha256.ComputeHash(stream.ToArray()); var builder = new StringBuilder(hash.Length * 2); for (int index = 0; index < hash.Length; index++) builder.Append(hash[index].ToString("x2")); return builder.ToString(); } } } private static void WritePoint(Stream stream, SmoothedPathPoint point) { if (point == null) throw new ArgumentException("稳定路径摘要不能包含空点。", nameof(point)); WriteDouble(stream, point.X); WriteDouble(stream, point.Y); WriteDouble(stream, point.Heading); WriteDouble(stream, point.UnwrappedHeading); WriteDouble(stream, point.ArcLength); WriteInt32(stream, (int)point.Direction); WriteDouble(stream, point.GeometricCurvature); WriteDouble(stream, point.VehicleCurvature); WriteDouble(stream, point.BodyClearance); WriteBoolean(stream, point.IsGearSwitchPoint); WriteInt32(stream, (int)point.Source); } private static void WriteSegment(Stream stream, SmoothedPathSegment segment) { if (segment == null) throw new ArgumentException("稳定路径摘要不能包含空方向段。", nameof(segment)); WriteInt32(stream, segment.SegmentIndex); WriteInt32(stream, (int)segment.Direction); WriteInt32(stream, segment.StartIndex); WriteInt32(stream, segment.EndIndex); WriteBoolean(stream, segment.StartsAtGearSwitch); WriteBoolean(stream, segment.EndsAtGearSwitch); } private static void WriteDouble(Stream stream, double value) { WriteInt64(stream, BitConverter.DoubleToInt64Bits(value)); } private static void WriteBoolean(Stream stream, bool value) { stream.WriteByte(value ? (byte)1 : (byte)0); } private static void WriteInt32(Stream stream, int value) { unchecked { stream.WriteByte((byte)value); stream.WriteByte((byte)(value >> 8)); stream.WriteByte((byte)(value >> 16)); stream.WriteByte((byte)(value >> 24)); } } private static void WriteInt64(Stream stream, long value) { unchecked { ulong bits = (ulong)value; for (int index = 0; index < 8; index++) stream.WriteByte((byte)(bits >> (index * 8))); } } }