标签导航:

如何使用反向查找树进行快速一次性电子邮件域检测

了解如何使用反向 trie 来有效检测一次性电子邮件域。使用专为快速、精确的结果而定制的可扩展、内存高效的解决方案来优化您的域名查找。

  • 阅读我网站上的文章
  • 使用免费的一次性电子邮件域名检测器

一次性电子邮件可能会导致虚假注册和垃圾邮件等问题。用户从数千个临时电子邮件生成器之一中获取一个地址并将其交给。即使是电子邮件正则表达式的 goat 也无法拯救您。

就我个人而言,我发现拥有所有一次性电子邮件域的大列表是最简单但最有效的解决方案。但在组装该列表并启动 for ... of 循环来检查它之前,请考虑一下 o(n) 复杂度!

识别它们的一个好方法是使用反向 trie,这是一种用于快速查找的高效数据结构。

什么是反向特里树?

首先,我们来了解一下什么是 trie。它是一种数据结构,其中字符串为:

  • 切碎,逐个字符
  • 组装成树形结构

例如,如果我们喂蟒蛇、兄弟、布里干酪,它会使用 map 将它们组装为:

b
 ├── o ── a
 └── r ── o  
     └─── i ── e

这种方法允许直接查找,而无需循环遍历整个列表。每个角色都引导着更深入的搜索。

它以内存换取效率。查找字符串所花费的时间并不取决于列表的大小,而是取决于字符串的长度!

反向 trie 以相反的顺序存储字符串,非常适合域:

  • mailinator.com 变为 moc.rotanliam
  • 垃圾邮件.com 变为 moc.liambhsart

关于此实施的注意事项

通过反转域名,搜索从 tld(例如 .com)开始,该域名在许多域名之间共享。为了进一步优化,它将 tld 存储为单个键 (com),而不是将其拆分为字符。域的其余部分遵循标准的 trie 结构。

反向 trie 域实现

由于这是一个树结构,每个节点都会引用它的子节点:

type trienode = map<string, trienode>;

首先,将 tld 与域的其余部分分开的实用程序函数:

private splittldfromrest(input: string) {
    const dot = input.lastindexof('.');
    const tld = input.substring(dot + 1);
    const rest = input.substring(0, dot);
    return [tld, rest];
}

使用lastindexof 确保像 foo.bar.baz.com 这样的子域得到正确处理。

接下来,构造函数将组装 trie:

export class reversetriedomains {
    private root: trienode = new map();

    // ...

    constructor(...domains: string[]) {
        for (const domain of domains) {
            // for "didof.dev"
            const [tld, rest] = this.splittldfromrest(domain);
            // dev, didof

            // keep the refence to the tld node for final set
            let node = this.root.get(tld);
            if (!node) node = new map();

            // start from tld node, walk along the string in reverse
            let currentnode: trienode = node;
            for (let i = rest.length - 1; i >= 0; i--) {
                const char = rest[i];
                let childnode = currentnode.get(char);
                if (!childnode) {
                    childnode = new map();
                    currentnode.set(char, childnode);
                }
                currentnode = childnode;
            }

            this.root.set(tld, node);
        }
    }
}

要检查域是否是一次性的,请遍历 trie:

export class ReverseTrieDomains {
    // ...

    public has(domain: string) {
        const [TLD, rest] = this.splitTLDFromRest(domain)

        const node = this.root.get(TLD)
        if (!node) return false

        let currentNode: TrieNode = node
        let isFullDomainFound = false
        for (let i = rest.length - 1; i >= 0; i--) {
            const char = rest[i]
            const childNode = currentNode.get(char)
            console.log(i, char, childNode)
            if (!childNode) return false
            currentNode = childNode
            if (i === 0) {
                isFullDomainFound = currentNode.size === 0;
            }
        }

        return isFullDomainFound
    }
}

结论

使用反向 trie 有几个好处:

  • 快速查找:逐步遍历字符以获得快速结果。
  • 内存效率:.com等常见后缀仅存储一次。
  • 可扩展性:轻松处理大型域列表。

如果您正在处理一次性电子邮件,这是一个可以实施的智能、可扩展的解决方案。