2010-03-31 18 views
5

Stiamo usando JCaptcha per uno strumento captcha in una piccola applicazione che la mia squadra sta scrivendo. Tuttavia, proprio durante il periodo di sviluppo (su una piccola squadra - 4 di noi), abbiamo eseguito una serie di parolacce e altre parole potenzialmente offensive per i captcha reali. C'è un modo per filtrare parole potenzialmente offensive in modo che non vengano presentate all'utente?C'è un modo per filtrare le parole offensive da Jcaptcha?

+3

Ogni parola è una "parola potenzialmente offensivo" a qualcuno. – Will

+1

il punto dei captcha è che un programma non può "leggerli" e capire quale parola sia.A meno di trovare una fonte diversa per i captcha, penso che sei sfortunato – Holograham

+0

@Holograham Sì, posso essere costretto a usare JCaptcha, sfortunatamente, a meno che non riesca a trovare altri strumenti che posso impacchettare e ci permette di fare le verifiche da solo server. Abbiamo anche bisogno di supporto per l'internazionalizzazione e la conformità 508 (file audio), che JCaptcha supporta. Ho a che fare con un gruppo di architetti molto severo (sigh). Mi piacerebbe usare re-captcha (che, credo, ha già i suoi filtri per questo genere di cose), ma il gruppo di architettura l'ha bloccato. – elduff

risposta

5

ho passato il tempo a scaricare JCaptcha e guardando la fonte. In pratica funziona come JCatpcha ogni singolo captcha là fuori oltre reCAPTCHA. Quindi quello che vuoi è banale.

JCaptcha sta usando il semplice concetto di una WordGenerator, che è e l'interfaccia:

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

Cerchiamo di ignorare localizzazione.

utilizzo tipico è così:

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

Nelle loro unit test possiamo vedere, a scopo di test:

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

noti che abbiamo INTERO controllo sul "WordGenerator" usato .

Eccone uno (di lavoro, perfettamente funzionante) generatore di parola che ho appena scritto:

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(); 
} 

Genera "parole" casuali come questi:

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

Si noti che, se si preferisce "parole reali" (come reCaptcha, ma reCaptcha sta usando la parola vera per un altro altogheter scopo - perché aiuta a scansione/OCR libri) non è un problema, è sufficiente modificare getword (...) a scegliere a caso le parole da un dizionario.

Ora come si fa a evitare parole insultanti per essere prelevati? Questo è banale. Qui ho solo dare un esempio (per favore, non discutere sul codice, è davvero solo un esempio che mostra come si potrebbe essere fatto):

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(); 
} 

Ora, se si vuole evitare parolacce, si probabilmente anche desidera evitare quelli vicini a parolacce (es. "fvck" e "dikk" ecc.). Questa è ancora una volta banale:

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; 
} 

scrittura del metodo "generateAllPermutationsWithLevenhsteinEditDistanceOne (w)" viene lasciato come exercice al lettore.

+1

quod erat demonstrandum – SyntaxT3rr0r

+0

@chris_l: il tuo problema sta nell'incapacità della tua mente di rendersi conto che quando si tratta di sicurezza c'è un'asimetria: il "difensore" ha a disposizione più informazioni dell'aggressore. Il tuo intero vagabondaggio è * esattamente * identico a qualcuno che direbbe * "PKCS non funziona perché non puoi moltiplicare due numeri primi enormi perché non puoi calcolare due numeri primi enormi" *. Che è un argomento completamente circolare che * precisi * manca il punto per cui PKCS funziona e perché Captcha funziona. Ci ** DEVE ** essere un modo per verificare che una risposta sia corretta (o errata). Abbiamo le informazioni sulle parole sul server. – SyntaxT3rr0r

+0

btw che genera tutte le permutazioni che hanno una modifica di Levenhstein La distanza di una è più semplice che calcolare la distanza di modifica stessa. – SyntaxT3rr0r

Problemi correlati