有没有办法过滤掉Jcaptcha的令人反感的话?

eld*_*uff 5 java captcha

我们正在使用JCaptcha作为我的团队正在编写的小应用程序中的验证码工具.然而,就在开发期间(在一个小团队 - 我们中的4个人),我们遇到了许多诅咒词和其他可能令人反感的词,用于实际的验证码.有没有办法过滤掉潜在的冒犯性词语,以便它们不会呈现给用户?

Syn*_*r0r 5

我花时间下载JCaptcha并查看源代码.基本上JCatpcha就像ReCaptcha那样就像每一个验证码一样.因此,你想要的是微不足道的.

JCaptcha使用的是WordGenerator的非常简单的概念,它是和接口:

public interface WordGenerator {
    String getWord(Integer length);
    String getWord(Integer length, Locale locale);
}
Run Code Online (Sandbox Code Playgroud)

让我们忽略本地化.

典型用法是这样的:

WordGenerator words = ...
WordToImage word2image = new SimpleWordToImage();
ImageCaptchaFactory factory = new GimpyFactory(words, word2image);
pixCaptcha = factory.getImageCaptcha();
Run Code Online (Sandbox Code Playgroud)

在他们的单元测试中,我们可以看到,为了测试目的:

    WordGenerator words = new DummyWordGenerator("TESTING");
    WordToImage word2image = new SimpleWordToImage();
    ImageCaptchaFactory factory = new GimpyFactory(words, word2image);
    pixCaptcha = factory.getImageCaptcha();
Run Code Online (Sandbox Code Playgroud)

需要注意的是,我们有所使用的"WordGenerator"控制.

这是我刚写的一个(工作的,功能齐全的)字生成器:

private static final Random r = new Random( System.currentTimeMillis() );

public String getWord( final Integer length ) {
    final StringBuilder sb = new StringBuilder();
    for (int i = 0; i < length; i++) {
        final int rnd = r.nextInt( 52 );
        final char c = (char) (rnd < 26 ? 'a' + rnd : 'A' + (rnd-26));
        sb.append( c );
    }
    return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)

它生成随机的"单词",如下所示:

fqXVxId
cdVWBSZ
zXeJFaY
aeoSeEb
OuBfzvL
unYewjG
EhbzRup
GkXkTyQ
yDGnHmh
mRFgHWM
FFBkTLF
DvCHIIT
fDmjqLH
XMWSOpa
muukLLN
jUedgYK
FlbWARe
WohMMgZ
lmeLHau
djHRqlc
Run Code Online (Sandbox Code Playgroud)

请注意,如果您更喜欢"真实的单词"(如reCaptcha,但reCaptcha使用真正的单词用于其他目的altogheter - 因为它有助于扫描/ OCRing书籍!)这不是问题,只需更改getWord(...)随机选择字典中的单词.

现在,你如何防止侮辱性的话被捡起来?这是微不足道的.在这里我只举一个例子(请,没有关于代码争论,它真的只是一个示例,说明它是如何做到):

private static final Set<String> s = new HashSet<String>();

static {
    s.add( "f**k" );
    s.add( "suck" );
    s.add( "dick" );
}

private static final Random r = new Random( System.currentTimeMillis() );

public String getWord( Integer length ) {
    String cand = getRandomWord( length );
    while ( isSwearWord(cand) ) {
        cand = getRandomWord( length );
    }
    return cand;
}

private boolean isSwearWord( final String w ) {
    return s.contains( w.toLowerCase() );
}

public String getRandomWord( final Integer length ) {
    final StringBuilder sb = new StringBuilder();
    for (int i = 0; i < length; i++) {
        final int rnd = r.nextInt( 52 );
        final char c = (char) (rnd < 26 ? 'a' + rnd : 'A' + (rnd-26));
        sb.append( c );
    }
    return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)

现在,如果你想防止骂人的话,你可能想阻止那些接近宣誓词(如"fvck""dikk"等).这又是微不足道的:

 private boolean isSwearWord( final String w ) {
    List<String> ls = generateAllPermutationsWithLevenhsteinEditDistanceOne(w);
    for ( final String cand : ls ) {
        if ( s.contains( cand.toLowerCase()) ) {
            return true;
        }
    }
    return false;
}
Run Code Online (Sandbox Code Playgroud)

编写方法"generateAllPermutationsWithLevenhsteinEditDistanceOne(w)"留给读者作为练习.