Существует ли способ отфильтровать оскорбительные слова от Jcaptcha?

Мы используем JCaptcha для инструмента капчи в небольшом приложении, которое пишет моя команда. Однако только в течение времени разработки (в малочисленной команде - 4 из нас), мы натыкались на многие слова проклятия и другие потенциально оскорбительные слова для фактических капчей. Существует ли способ отфильтровать потенциально оскорбительные слова так, чтобы они не были представлены пользователю?

5
задан elduff 31 March 2010 в 19:41
поделиться

1 ответ

Я потратил время на скачивание JCaptcha и изучение исходников. В основном JCatpcha работает как любая другая капча, кроме ReCaptcha. Следовательно, то, что вы хотите, тривиально.

JCaptcha использует очень простую концепцию WordGenerator, которая представляет собой и интерфейс:

public interface WordGenerator {
    String getWord(Integer length);
    String getWord(Integer length, Locale locale);
}

Давайте проигнорируем локализацию.

Типичное использование выглядит так:

WordGenerator words = ...
WordToImage word2image = new SimpleWordToImage();
ImageCaptchaFactory factory = new GimpyFactory(words, word2image);
pixCaptcha = factory.getImageCaptcha();

В их модульных тестах мы можем увидеть, в целях тестирования:

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

Обратите внимание, что у нас есть ENTIRE контроль над используемым "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();
}

Он генерирует случайные "слова", как эти:

fqXVxId
cdVWBSZ
zXeJFaY
aeoSeEb
OuBfzvL
unYewjG
EhbzRup
GkXkTyQ
yDGnHmh
mRFgHWM
FFBkTLF
DvCHIIT
fDmjqLH
XMWSOpa
muukLLN
jUedgYK
FlbWARe
WohMMgZ
lmeLHau
djHRqlc

Обратите внимание, что если вы предпочитаете "реальные слова" (как reCaptcha, но reCaptcha использует реальные слова для другой цели - потому что это помогает сканировать/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();
}

Теперь, если вы хотите предотвратить бранные слова, вы, вероятно, также хотите предотвратить слова, близкие к бранным (например, "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;
}

Написание метода "generateAllPermutationsWithLevenhsteinEditDistanceOne(w)" оставим читателю в качестве упражнения.

5
ответ дан 14 December 2019 в 19:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: