using System.Security.Cryptography; using System.Text; namespace StellaOps.Scanner.ReachabilityDrift; internal static class DeterministicIds { internal static readonly Guid CodeChangeNamespace = new("a420df67-6c4b-4f80-9870-0d070a845b4b"); internal static readonly Guid DriftResultNamespace = new("c60e2a63-9bc4-4ff0-9f8c-2a7c11c2f8c4"); internal static readonly Guid DriftedSinkNamespace = new("9b8ed5d2-4b6f-4f6f-9e3b-3a81e9f85a25"); public static Guid Create(Guid namespaceId, params string[] segments) { var normalized = string.Join( '|', segments.Select(static s => (s ?? string.Empty).Trim())); return Create(namespaceId, Encoding.UTF8.GetBytes(normalized)); } public static Guid Create(Guid namespaceId, ReadOnlySpan nameBytes) { Span namespaceBytes = stackalloc byte[16]; namespaceId.TryWriteBytes(namespaceBytes); Span buffer = stackalloc byte[namespaceBytes.Length + nameBytes.Length]; namespaceBytes.CopyTo(buffer); nameBytes.CopyTo(buffer[namespaceBytes.Length..]); Span hash = stackalloc byte[32]; SHA256.TryHashData(buffer, hash, out _); Span guidBytes = stackalloc byte[16]; hash[..16].CopyTo(guidBytes); guidBytes[6] = (byte)((guidBytes[6] & 0x0F) | 0x50); guidBytes[8] = (byte)((guidBytes[8] & 0x3F) | 0x80); return new Guid(guidBytes); } }