如何优化以下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 表单只是and
和or
操作,这些可以很容易地用作 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=
语法。