【问题标题】:Compare ACL of two folders比较两个文件夹的 ACL
【发布时间】:2019-03-15 12:21:28
【问题描述】:

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

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

有更好的方法吗?

【问题讨论】:

    标签: c# acl


    【解决方案1】:

    我会使用来自 LINQ 的 SequenceEqual,因为 AuthorizationRuleCollection 实现了 IEnumerable。唯一的问题是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);
    

    【讨论】:

    • 由于两个集合可以有不同的顺序,这会给你错误的结果。
    【解决方案2】:

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

            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;
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-15
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多