LDAP - 优化过滤器


LDAP - optimising filter

如何优化以下LDAP过滤器以删除代码中的重复项?

(|(&(cn=PATH*)(cn=*2013*)(|(cn=*_S1_*)(cn=*_1_*)))(&(cn=MICR*)(cn=*2013*)(|(cn=*_S1_*)(cn=*_1_*))))

一般来说,要进行优化,最重要的一件事就是确保 LDAP 服务器上有正确的索引。不过,这无助于简化实际的过滤器...这个问题(几乎)是简单的布尔表达式简化。

首先,从 LDAP 过滤器前缀表示法转换为中缀表示法(一些示例算法)。我为过滤器项目使用占位符符号:

a  cn=PATH*
b  cn=*2013*
c  cn=*_S1_*
d  cn=*_1_*
e  cn=MICR*

所以这个前缀表示法过滤器

(|(&(a)(b)(|(c)(d)))(&(e)(b)(|(c)(d))))

成为此中缀表示法筛选器:

 (a&b&(c|d))|(e&b&(c|d))

然后使用任何正常的布尔表达式优化器/简化器,我很懒,所以我会让 Wolfram 来做。

现在找出最简单的最小表单结果,DNF 或 CNF 表单只是andor操作,这些可以很容易地用作 LDAP 过滤器(任何没有⊻"xor"的东西都可能是好的)。CNF 在这里显然更简单:

DNF   (a ∧ b ∧ c) ∨ (a ∧ b ∧ d) ∨ (b ∧ c ∧ e) ∨ (b ∧ d ∧ e)
CNF   (a ∨ e) ∧ b ∧ (c ∨ d)

("∧"是"和","∨"是"或")

将其变回前缀过滤器并替换您获得的符号:

(& (| (cn=PATH*)(cn=MICR*) )
   (cn=*2013*)
   (| (cn=*_S1_*)(cn=*_1_*) )
)

还有最后一个微不足道的优化,当某些类型的子字符串匹配不重叠时,您可以合并它们而不使用运算符:

(& (| (cn=PATH*2013*)(cn=MICR*2013*))
   (| (cn=*_S1_*)(cn=*_1_*))
)

如果您需要以编程方式对任意过滤器执行此操作,则可以轻松找到代码来执行前缀/中缀转换,以及PHP中的布尔表达式优化,这些都是解析器和表达式计算中的常见问题。

我怀疑当您有零个或其中一个时,您需要将术语与前缀/中缀/后缀字符串进行特殊情况合并,我不知道这样一个过程的名称。在任何情况下,您都需要它来了解 LDAP attribute=语法。