【问题标题】:Ensure password does not contain dictionary words确保密码不包含字典单词
【发布时间】:2018-05-03 09:33:56
【问题描述】:

我打算在java中实现一个解决方案,它检查用户密码是否不包含字典单词,无论是英语、西班牙语、德语还是法语。

我有来自这里的单词列表: ftp://ftp.openwall.com/pub/wordlists/languages/English/

我正在考虑使用 HashMap 或使用像 redis 这样的缓存,它将包含字典中的所有单词作为单词。虽然这可能效率不高。

什么是最好的执行方式?

【问题讨论】:

  • 请不要实现那个,这个系统有什么意义?您的目标是强迫用户在便利贴上写下他们的密码并将其粘贴到他们的显示器上吗?因为这就是你将要得到的。
  • a little explaination(作为漫画,但很严肃)
  • @luk2302 :我同意,但是作为密码策略一部分的替代方案是什么......
  • 没有密码策略。您的策略越详细,密码就越有可能被记录下来。如果你真的想要一个,你可以选择“10+ 个字符并包含数字 + 字母”,所有更严格的东西都令人讨厌。

标签: java spring dictionary


【解决方案1】:

如果这确实是您的要求,我建议使用Trie 数据结构,该结构非常适合在字典中快速查找单词。

您可以在 org.apache.commons.collections4 中获得 trie 的实现。见https://commons.apache.org/proper/commons-collections/javadocs/api-release/org/apache/commons/collections4/Trie.html

使用 trie,您需要从字典中构建它并将其保存在内存中。然后你需要从右到左遍历字符串,看看你是否可以在 trie 中查找结果。如果没有找到结果,则字典中没有密码的任何部分。

尝试在寻找字符串模式方面非常有效,因为它们使用树状结构。

如果您想在 Maven 项目中使用 Apache Commons trie,请使用此导入依赖项:

<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-collections4 -->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-collections4</artifactId>
    <version>4.0</version>
</dependency>

这是一个简单的玩具示例,它在字符串“hellothere”中查找字典单词:

import com.google.common.collect.ImmutableMap;
import org.apache.commons.collections4.Trie;
import org.apache.commons.collections4.trie.PatriciaTrie;
import org.apache.commons.collections4.trie.UnmodifiableTrie;

import java.util.ArrayList;
import java.util.Map;
import java.util.stream.IntStream;

public class TrieDict {

    public static void main(String[] args) {
        Trie<String, String> trie = new UnmodifiableTrie<>(new PatriciaTrie<>(fillMap()));
        String pwd = "hellothere";
        System.out.println(extractDictMatches(trie, pwd));
    }

    // Provides a dictionary
    private static Map<String, String> fillMap() {
        return ImmutableMap.<String, String>builder().
                put("there", "there").
                put("is", "is").
                put("word", "word").
                put("here", "here").
                put("hell", "hell").
                build();
    }

    private static ArrayList<String> extractDictMatches(Trie<String, String> trie, String pwd) {
        return IntStream.range(0, pwd.length()).collect(ArrayList::new, (objects, i) -> {
            String suffix = pwd.substring(i);
            IntStream.rangeClosed(0, suffix.length()).forEach(j -> {
                String suffixCut = suffix.substring(0, j);
                if (suffixCut.length() > 2) {
                    if (trie.containsKey(suffixCut)) {
                        objects.add(suffixCut);
                    }
                }
            });
        }, (objects, i) -> {
        });
    }
}

这将打印出来:

[hell, there, here]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 2016-03-04
    • 1970-01-01
    相关资源
    最近更新 更多