比较两个文件夹的ACL

时间:2019-03-15 12:21:28

标签: c# acl

您如何比较两个不同文件夹的AuthorizationRuleCollection?我想知道ACL是否相同。

我的解决方案是遍历每个项目并计算IdentityReference.Value + AccessMask的哈希值。然后将它们汇总起来,比较每个集合的总数。

有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

由于SequenceEqual实现了IEnumerable,因此我将使用LINQ中的AuthorizationRuleCollection。唯一的问题是AuthorizationRule不会覆盖object.Equals(),这意味着我们需要像这样提供自定义IEqualityComparer<AuthorizationRule>

public class AuthorizationRuleEqualityComparer : IEqualityComparer<AuthorizationRule>
{
    public static readonly AuthorizationRuleEqualityComparer Instance = new AuthorizationRuleEqualityComparer();

    private AuthorizationRuleEqualityComparer()
    {
    }

    public bool Equals(AuthorizationRule l, AuthorizationRule r)
    {
        // Compare more fields if needed.
        return l.IdentityReference == r.IdentityReference;
    }

    public int GetHashCode(AuthorizationRule rule)
    {
        return rule.IdentityReference.GetHashCode();
    }
}

用法:

AuthorizationRuleCollection arc1;
AuthorizationRuleCollection arc2;
var equal = arc1
    .OfType<AuthorizationRule>()
    .SequenceEqual(
        arc2.OfType<AuthorizationRule>(),
        AuthorizationRuleEqualityComparer.Instance);

答案 1 :(得分:0)

即使集合内的顺序不同,这似乎也可以正常工作

        internal static bool IsEqual(this AuthorizationRuleCollection authorizationRuleCollectionA, AuthorizationRuleCollection authorizationRuleCollectionB)
    {
        if (authorizationRuleCollectionA.Count != authorizationRuleCollectionB.Count)
        {
            return false;
        }

        int hash1 = CalculateHash(authorizationRuleCollectionA);
        int hash2 = CalculateHash(authorizationRuleCollectionB);

        return hash1 == hash2;
    }

    /// <summary>
    /// Source: https://stackoverflow.com/a/263416/10585750
    /// </summary>
    /// <param name="authorizationRuleCollection"></param>
    private static int CalculateHash(AuthorizationRuleCollection authorizationRuleCollection)
    {
        unchecked
        {
            int hash = 17;
            foreach (FileSystemAccessRule fileSystemAccessRule in authorizationRuleCollection)
            {
                hash += CalculateHash(fileSystemAccessRule);
            }
            return hash;
        }
    }

    private static int CalculateHash(FileSystemAccessRule fileSystemAccessRule)
    {
        unchecked
        {
            int hash = 23 * fileSystemAccessRule.IdentityReference.Value.GetHashCode()
                * fileSystemAccessRule.InheritanceFlags.ToString().GetHashCode()
                * fileSystemAccessRule.IsInherited.ToString().GetHashCode()
                * fileSystemAccessRule.PropagationFlags.ToString().GetHashCode()
                * fileSystemAccessRule.FileSystemRights.ToString().GetHashCode()
                * fileSystemAccessRule.AccessControlType.ToString().GetHashCode();
            return hash;
        }
    }