2010-03-31 13 views
5

Estamos usando JCaptcha para una herramienta de captcha en una pequeña aplicación que está escribiendo mi equipo. Sin embargo, solo durante el tiempo de desarrollo (en un equipo pequeño, 4 de nosotros), nos encontramos con una serie de palabras de maldición y otras palabras potencialmente ofensivas para los captchas reales. ¿Hay alguna forma de filtrar palabras potencialmente ofensivas para que no se presenten al usuario?¿Hay alguna forma de filtrar las palabras ofensivas de Jcaptcha?

+3

Cada palabra es una "palabra potencialmente ofensiva" para alguien. – Will

+1

El punto de captchas es que un programa no puede 'leerlos' y descubrir qué palabra es.A falta de encontrar una fuente diferente para los captchas, creo que no tienes suerte – Holograham

+0

@Holograham Sí, me veo obligado a usar JCaptcha, lamentablemente, a menos que pueda encontrar otra herramienta que pueda empaquetar y nos permita hacer las verificaciones por nuestra cuenta. servidor. También necesitamos soporte para la internacionalización y el cumplimiento 508 (archivos de audio), que JCaptcha sí admite. Estoy lidiando con un grupo de arquitectura muy estricto (suspiro). Me encantaría usar re-captcha (que, creo, ya tiene sus propios filtros para este tipo de cosas), pero el grupo de arquitectura lo ha rechazado. – elduff

Respuesta

5

Pasé tiempo descargando JCaptcha y mirando la fuente. Básicamente, JCatpcha funciona como por cada captcha, además de ReCaptcha. Por lo tanto, lo que quiere es trivial.

JCaptcha está utilizando el concepto muy simple de un WordGenerator, que es e interfaz:

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

Ignoremos localización.

El uso típico es la siguiente:

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

En sus pruebas de unidad podemos ver, para el propósito de prueba:

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

en cuenta que tenemos TODA control en el "WordGenerator" utilizado .

Aquí hay un generador de palabras (de trabajo, totalmente funcional) que acabo de escribir:

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 "palabras" al azar como éstas:

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

Tenga en cuenta que si usted prefiere "palabras verdaderas" (como reCaptcha, pero reCaptcha está usando palabras reales para otro fin alto - ¡porque ayuda a escanear/OCRing books!) no es un problema, simplemente cambie getWord (...) para seleccionar palabras al azar de un diccionario.

Ahora, ¿cómo evitar que se recojan las palabras insultantes? Esto es trivial. Aquí acabo de dar un ejemplo (por favor, no hay discusión sobre el código, no deja de ser uno ejemplo que muestra cómo se podría hacerse):

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

Ahora bien, si desea evitar malas palabras, se probablemente también desea evitar aquellos cerca de malas palabras (por ejemplo, "fvck" y "dikk" etc.). Esto es una vez más trivial:

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

escritura del método "generateAllPermutationsWithLevenhsteinEditDistanceOne (w)" se deja como exercice para el lector.

+1

quod erat demonstrandum – SyntaxT3rr0r

+0

@chris_l: su problema radica en que su mente no se da cuenta de que cuando se trata de seguridad hay una asimetría: el "acusado" tiene más información disponible que el atacante. Todo lo que dices es * exactamente * idéntico a alguien que diría * "PKCS no funciona porque no puedes multiplicar dos números primos enormes porque no puedes factorizar dos números primos enormes" *. Que es un argumento completamente circular que * precisamente * no tiene en cuenta el punto por el cual funciona PKCS y por qué funciona Captcha. No ** DEBE ** ser una forma de verificar que una respuesta sea correcta (o incorrecta). Tenemos la información de palabras en el servidor. – SyntaxT3rr0r

+0

por generación de todas las permutaciones que tienen una Levenhstein Editar Distancia de uno es más fácil que calcular la distancia de edición en sí. – SyntaxT3rr0r

Cuestiones relacionadas