脚本来查找类似的电子邮件用户

时间:2014-04-09 19:54:10

标签: bash email

我们有一个邮件服务器,我正在尝试编写一个脚本,该脚本将查找具有相似名称的所有用户,以避免恶意用户冒充合法用户。例如,合法用户可能具有james2014@domain.com的名称,但恶意用户可以注册为james20l4@domain.com。如果您仔细注意,差异在于我用字母'l'(el)替换了数字'one'。所以我试着写一些可以咨询我的/var/vmail/domain/*并查找类似名称并提醒我(管理员)的内容。然后我将采取必要的步骤来做我需要的事情。非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

这样做的一个hacky方法是推导"标准化"您的用户名的版本,将它们作为映射到原始输入的键放在关联数组中,并使用它们来查找问题。

我在下面发布的示例使用bash associative arrays来存储从规范化名称到原始名称的映射,并使用tr来切换其他字符的某些字符(并完全删除其他字符)。

我假设您的用户列表适合内存;你还需要调整修改和删除字符的映射,以达到你在效果和误报之间最喜欢的平衡。如果您的列表不适合内存,您可以使用单个文件或文件系统来近似它,但老实说,如果您正在处理许多名称,那么使用非shell可能会更好编程语言。

<强>输入:

doc
dopey
james2014
happy
bashful
grumpy
james20l4
sleepy
james.2014
sneezy

<强>脚本:

#!/bin/bash
# stdin: A list of usernames. stdout: Pairs of names that match.
CHARS_TO_REMOVE="._\\- "
CHARS_TO_MAP_FROM="OISZql"
CHARS_TO_MAP_TO="0152g1"

normalize() {
  # stdin: A word. stdout: A modified version of the same word.
  exec tr "$CHARS_TO_MAP_FROM" "$CHARS_TO_MAP_TO" \
      | tr --delete "$CHARS_TO_REMOVE" \
      | tr "A-Z" "a-z"
}

declare -A NORMALIZED_NAMES
while read NAME; do
  NORMALIZED_NAME=$(normalize <<< "$NAME")
  # -n tests for non-empty strings, as it would be if the name were set already.
  if [[ -n ${NORMALIZED_NAMES[$NORMALIZED_NAME]} ]]; then
    # This name has been seen before! Print both of them.
    echo "${NORMALIZED_NAMES[$NORMALIZED_NAME]} $NAME"
  else
    # This name has not been seen before. Store it.
    NORMALIZED_NAMES["$NORMALIZED_NAME"]="$NAME"
  fi
done

<强>输出:

james2014 james20l4
james2014 james.2014