5

一般要求是我需要为不接受三个连续字母或数字的密码实现一种方法 - 所以没有'abc123'密码。

我需要一种方法来查看三个字母是否按顺序依次出现 - 显然,对于任何一种语言,这都相当简单,但每种 unicode 语言的通用代码似乎让我无法理解。

我假设首先我需要一种方法来确定这三个字符是否使用相同的语言,然后确定它们是否按顺序排列。在 unicode 中,还有一些语言没有以任何特定方式排序——因此需要有一种方法来判断我们是否使用一种有顺序的语言。

这是否像我想象的那样复杂,或者unicode中是否有Java库/固有模式允许这样的事情?

如果我要降低要求,以便我只是在数字上比较 unicode 数字,是否有任何现实世界的场景会遇到麻烦?即,是否有人以一种有效的方式选择包含一种语言的两个结尾字母和下一种语言的第一个字母的密码?

4

4 回答 4

2

如果我是你,我会得到 char 的 unicode 位置并检查下一个字符的位置是否为第一个 + 1 - 这应该适用于所有语言,因为应该对 Unicode 代码点进行排序。

于 2013-11-10T22:18:48.120 回答
1

可能Character.isLetter(c)符合您的需求。以下单元测试运行低谷。

package snippets;

import static org.junit.Assert.*;

public class LetterTest {

    @Test
    public void test3Uni() throws Exception {
        String s = "汉语漢語";
        for (char c : s.toCharArray()) {
            assertTrue(Character.isLetter(c));
        }
    }

}

也有一个Character.isDigit(d)

于 2013-11-10T22:31:25.450 回答
0

您可以搜索在同一个Unicode 块中是否有 3 个连续的代码点。有一个额外的条件isLetterOrDigit(cp)

Character.UnicodeBlock oldBlock = 0;
int oldCp = 0;
int n = 0;
for (int i = 0; i < s.length(); ) {
    int cp = s.codePointAt(i);
    i += Character.charCount(cp);
    Character.UnicodeBlock block = Character.UnicodeBlock.of(cp);
    if (n != 0 && block == oldBlock && cp == oldCp + 1 && isLetterOrDigit(cp)) {
        ++n;
        oldCp = cp;
        if (n >= 0) {
            return false;
        }
    } else {
        n = isLetterOrDigit(cp) ? 1 : 0;
        oldCp = cp;
        oldBlock = block;
    }
}
return true;
于 2013-11-10T22:47:11.540 回答
0

这不是一个有意义的要求。

首先,即使可以定义每个代码点的绝对序列,Unicode 也是一个移动的目标。每个版本都会将新的代码点添加到未分配的间隙中。

来自Unicode Collat​​ion Algorithm Introduction

排序规则因语言和文化而异:德国人、法国人和瑞典人对相同的字符进行不同的排序。

Unicode 定义了一个默认的排序顺序,但它可能会违背用户的期望。说英语的人会认为stu是一个连续的序列。但考虑 U+00DF 锐利的 s ß。如果您将其包含在字符串中并使用英语语言环境 Java 排序规则进行排序,您最终将得到sßtu.

简介接着说:

对于未在特定语言中使用的脚本和字符,可能不存在明确的规则。例如,瑞典语和法语已经明确规定了对 ä 进行排序的不同规则(在 z 之后或作为与 a 有次要区别的重音字符),但都没有定义字符的顺序,例如 Ж、ש、♫、∞、◊ ,或⌂。

由于i18n的担忧,您不能期望单个排序对每个用户都有意义。您能做的最好的事情就是为个别语言构建一些启发式方法。

于 2013-11-11T14:25:38.743 回答