You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#如何计算含SID的注册表键字符串相似度(排除Levenshtein距离)

C# 实现带SID的注册表键相似度判定

核心逻辑

不要直接对全串计算编辑距离,注册表键为固定层级结构,SID仅出现在HKEY_USERS的下一级节点位置,先做结构归一化处理排除SID的干扰,再计算相似度即可满足需求。

具体实现步骤

1. 编写SID匹配规则

Windows SID的标准格式为S-数字-数字段串,仅包含数字和短横线,用正则即可快速识别:
^S-\d-(?:\d+-)+\d+$

2. 实现注册表键归一化方法

将输入的注册表键按\分割为层级片段,遍历所有片段,将符合SID格式的片段统一替换为占位符{SID},排除不同SID带来的无意义差异。

3. 相似度计算

  • 若两个键归一化后的结果完全相等,直接判定为100%相似
  • 若仍有差异,可对归一化后的字符串计算莱文斯坦距离,或按层级加权计算相似度(根节点、系统级节点权重高于自定义子节点,结果更贴合业务逻辑)

完整代码示例

using System;
using System.Linq;
using System.Text.RegularExpressions;

public static class RegistryKeySimilarity
{
    // SID匹配正则
    private static readonly Regex SidRegex = new Regex(@"^S-\d-(?:\d+-)+\d+$", RegexOptions.Compiled | RegexOptions.IgnoreCase);

    // 归一化注册表键
    private static string NormalizeRegistryKey(string key)
    {
        if (string.IsNullOrWhiteSpace(key)) return string.Empty;
        var segments = key.Split('\\');
        for (int i = 0; i < segments.Length; i++)
        {
            if (SidRegex.IsMatch(segments[i]))
            {
                segments[i] = "{SID}";
            }
        }
        return string.Join('\\', segments);
    }

    // 计算相似度(返回0-1的浮点数,1为完全相同)
    public static double GetSimilarity(string key1, string key2)
    {
        var normalized1 = NormalizeRegistryKey(key1);
        var normalized2 = NormalizeRegistryKey(key2);

        if (normalized1 == normalized2) return 1.0;

        // 归一化后仍有差异则计算莱文斯坦距离
        int distance = LevenshteinDistance(normalized1, normalized2);
        int maxLength = Math.Max(normalized1.Length, normalized2.Length);
        return maxLength == 0 ? 1.0 : 1 - (double)distance / maxLength;
    }

    // 莱文斯坦距离实现
    private static int LevenshteinDistance(string a, string b)
    {
        int[,] matrix = new int[a.Length + 1, b.Length + 1];
        for (int i = 0; i <= a.Length; i++) matrix[i, 0] = i;
        for (int j = 0; j <= b.Length; j++) matrix[0, j] = j;

        for (int j = 1; j <= b.Length; j++)
        {
            for (int i = 1; i <= a.Length; i++)
            {
                int cost = (a[i - 1] == b[j - 1]) ? 0 : 1;
                matrix[i, j] = Math.Min(Math.Min(matrix[i - 1, j] + 1, matrix[i, j - 1] + 1), matrix[i - 1, j - 1] + cost);
            }
        }
        return matrix[a.Length, b.Length];
    }
}

// 调用示例
public class Program
{
    public static void Main()
    {
        string key1 = @"Computer\HKEY_USERS\S-1-5-21-123456789-1234567890-123456789-1001\SomethingHere\SomethingHere";
        string key2 = @"Computer\HKEY_USERS\S-1-5-21-987654321-0987654321-987654321-1002\SomethingHere\SomethingHere";
        
        double similarity = RegistryKeySimilarity.GetSimilarity(key1, key2);
        Console.WriteLine($"相似度:{similarity:P0}"); // 输出:相似度:100%
    }
}

效果说明

你提到的两个仅SID不同的注册表键,经过归一化后会变成完全相同的字符串,相似度为100%,符合预期。如果还有其他层级的差异,也能通过编辑距离计算得到准确的相似度结果。

内容的提问来源于stack exchange,提问作者rlnnclt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 09:45:07