Apache Commons Text:特殊字符的随机字符串 java

Apache Commons Text: Random String for special characters java

我正在使用 apache commons-text:RandomStringGenerator 生成随机 String,如下所示:

//Utilities
private static RandomStringGenerator generator(int minimumCodePoint, int maximumCodePoint, CharacterPredicates... predicates) {
    return new RandomStringGenerator.Builder()
            .withinRange(minimumCodePoint, maximumCodePoint)
            .filteredBy(predicates)
            .build();
}

public static String randStringAlpha(int length) {
    return generator('A', 'z', CharacterPredicates.LETTERS).generate(length);
}

public static String randStringAlphaNum(int length) {
    return generator('1', 'z', CharacterPredicates.LETTERS, CharacterPredicates.DIGITS).generate(length);
}

//Generation
private void foo() {
    String alpha = randStringAlpha(255);
    String num = randStringAlphaNum(255);
}

我正在寻找一种方法来使用相同的库来生成以下内容:

  • A - 特殊字符(可以限制为键盘特殊字符)
  • B - α + A
  • C - 数 + A
  • D - alpha + num + A

    我已经检查了 CharacterPredicates enum 但它只有 LETTERSDIGITS 用于过滤。任何帮助将不胜感激!

    编辑:=========================================== ====

    我决定搁置我当前的解决方案以支持 答案。
    为了阐明 'special characters' 的范围,我实际上是在寻找这个子集:

    案例 A 的代码段:

    public static CharSequence asciiSpecial() {
        return asciiCharacters().toString().replaceAll("(\d|[A-z])","");
    }
    
  • 您可以将方法 generator 中的参数类型从 CharacterPredicates 修改为 CharacterPredicate 并编写您的自定义 CharacterPredicate 如:

    private static RandomStringGenerator generator(int minimumCodePoint, int maximumCodePoint, CharacterPredicate... predicates) {
        return new RandomStringGenerator.Builder()
                .withinRange(minimumCodePoint, maximumCodePoint)
                .filteredBy(predicates)
                .build();
    }
    
    public static String randSomething(int length) {
        return generator('1', 'z', new CharacterPredicate() {
            @Override
            public boolean test(int i) {
                return true; // Write your logic here
            }
        }).generate(length);
    }
    

    您的类别“特殊字符”非常模糊。只要您保持在 ASCII 范围内,所有字符都是字母、数字或“特殊字符”,但可以使用普通键盘输入。换句话说,您根本不需要为此指定过滤器。另一方面,当您离开 ASCII 范围时,您必须注意各种字符类别(例如,您不想在任意点插入随机组合字符),此外,没有通用测试是否一个字符可以用键盘输入(因为没有通用键盘)…

    但请注意,您尝试使用该库的代码已经比执行实际工作的代码大。例如。要获得随机字符串,您可以使用

    public static String randStringAlpha(int size) {
        return ThreadLocalRandom.current().ints('A', 'z'+1)
            .filter(Character::isLetter)
            .limit(size)
            .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
            .toString();
    }
    

    或可能更有效的变体

    public static String randStringAlpha(int size) {
        return ThreadLocalRandom.current().ints(size, 'A', 'Z'+1)
            .map(c -> ThreadLocalRandom.current().nextBoolean()? c: Character.toLowerCase(c))
            .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
            .toString();
    }
    

    没有任何第 3 方库。

    同样,您可以使用

    概括任务
    public static String randomString(int size, CharSequence validChars) {
        return ThreadLocalRandom.current().ints(size, 0, validChars.length())
            .map(validChars::charAt)
            .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
            .toString();
    }
    public static String randomString(int minSizeIncl, int maxSizeIncl, CharSequence valid) {
        return randomString(
            ThreadLocalRandom.current().nextInt(minSizeIncl, maxSizeIncl), valid);
    }
    public static CharSequence asciiLetters() {
        return IntStream.concat(IntStream.rangeClosed('A','Z'), IntStream.rangeClosed('a','z'))
            .collect(StringBuilder::new,StringBuilder::appendCodePoint,StringBuilder::append);
    }
    public static CharSequence asciiLetterOrDigit() {
        return IntStream.concat(asciiLetters().chars(),IntStream.rangeClosed('0', '9'))
            .collect(StringBuilder::new,StringBuilder::appendCodePoint,StringBuilder::append);
    }
    public static CharSequence asciiCharacters() {
        return IntStream.rangeClosed('!', '~')
            .collect(StringBuilder::new,StringBuilder::appendCodePoint,StringBuilder::append);
    }
    

    您可以结合使用两种方法,例如
    RandomString.randomString(10, asciiLetters()),
    RandomString.randomString(10, asciiLetterOrDigit()),或
    RandomString.randomString(10, asciiCharacters()),分别。他们的可变大小对应物,如 RandomString.randomString(10, 20, asciiCharacters()).

    CharSequence 可以在多个字符串生成调用之间重复使用,类似于构建 RandomStringGenerator 并多次使用它。