Python 如何安全地确定电子邮件地址是否在列表中?

Python 如何安全地确定电子邮件地址是否在列表中?,python,email-validation,Python,Email Validation,我的任务是编写一个系统,确定提供的电子邮件地址是否在列表中。检查列表中是否有字符串通常是一项简单的任务,但电子邮件地址很复杂。例如,如果我向personname@gmail.com和个人。name@gmail.com,两封电子邮件都将到达同一帐户。据我所知,还有其他几种方法可以让用户拥有两个不同的电子邮件地址字符串,最终到达帐户(用下划线替换句点,在用户名后添加+字符,改变字母大小写等) 此系统的用户有一个动机,即提供多个电子邮件地址,这些地址愚弄了列表检查,但却导致了相同的帐户(personn

我的任务是编写一个系统,确定提供的电子邮件地址是否在列表中。检查列表中是否有字符串通常是一项简单的任务,但电子邮件地址很复杂。例如,如果我向
personname@gmail.com
个人。name@gmail.com
,两封电子邮件都将到达同一帐户。据我所知,还有其他几种方法可以让用户拥有两个不同的电子邮件地址字符串,最终到达帐户(用下划线替换句点,在用户名后添加+字符,改变字母大小写等)

此系统的用户有一个动机,即提供多个电子邮件地址,这些地址愚弄了列表检查,但却导致了相同的帐户(
personname@gmail.com
个人。name@gmail.com
)。我想找到一些方法来确定两个电子邮件地址是否都会指向同一个电子邮件提供商帐户(最好使用Python,尽管我可以移植任何解决方案)


我的第一个解决方案是尝试列举上述技巧,并将它们颠倒过来,以获得某种常见形式的电子邮件地址。例如,删除所有下划线和点,删除第一个+和@符号之间的所有内容,并将电子邮件转换为所有小写字母。问题是,我不能100%确定这是一个所有可能技巧的详尽列表,也不知道这些技巧是否适用于所有提供商。是否有比此方法更可靠的库或通用方法来执行此类检查?我是否不得不执行这些有限的检查,然后承担更聪明的用户成功欺骗我的系统的成本?

不幸的是,您描述的行为完全取决于电子邮件提供商。Gmail可能会忽略某些字符,但其他提供商不会,这意味着你的规则可能会生成错误的匹配。SMTP规范明确指出,您不能对电子邮件提供商如何解释电子邮件地址做出任何假设,因为处理方式完全取决于他们(以粗体突出显示):

地址通常由用户和域规范组成。
标准邮箱命名约定定义为 “当地的-part@domain"; 现代用法允许使用更广泛的 应用程序比简单的“用户名”。因此,由于 当中间主机尝试 通过修改它们来优化传输,本地部分必须 仅由中指定的主机解释和分配语义 地址的域部分


因此,电子邮件没有通用的规则。你所能做的就是为每个电子邮件提供商使用一套单独的规则,这会给你带来一些成功,但是解决方案永远不会完美。

personname
person.name
不会到达相同的电子邮件帐户可能有一个已发布的电子邮件地址格式规范,其中描述了哪些别名有效,哪些别名无效。您不必费心检查电子邮件提供商是否支持它,因为您可以合理地假设它不会将它们视为不同的地址(它可能不会传递它们)。一旦你有了规范,你的想法就是创建一个规范的电子邮件列表并对照它进行检查。据我所知,你所描述的技巧适用于Gmail地址,但一般来说并不常见。其他服务可能已经采用了它们,但可能有许多服务是针对
个人的。name@example.com
personname@example.com
作为不同的地址。这是一个非常广泛的问题,不太适合原样-您可能需要检查文档并尝试将其缩小到特定的范围(尤其是代码级别)你在这方面遇到了麻烦。不过,从高层次来看,简单的答案是“不”。没有一种通用的、可靠的方法可以仅仅通过检查一组电子邮件地址所组成的字符串来确定它们是否最终出现在同一个邮箱中。无论你在构建什么,都应该尽量避免依赖这样一个过程。你所做的是在没有模式的地方寻找模式。当然,你总会在随机性中找到一些。