2010-02-05 9 views
12

Tengo un "mnemonic" función la generación de contraseñas que es algo como esto:contraseña mnemotécnico algoritmo de generación de teclados QWERTY

function Mnemonic($mnemonic) 
{ 
    $result = null; 
    $charset = array(str_split('aeiou', 1), str_split('bcdfghjklmnpqrstvwxyz', 1)); 

    for ($i = 1; $i <= $mnemonic; $i++) 
    { 
     $result .= $charset[$i % 2][array_rand($charset[$i % 2])]; 
    } 

    return $result; 
} 

Básicamente esto genera una cadena con $mnemonic longitud donde cada personaje extraño es una consonante y cada carácter par es una vocal. Si bien entiendo que esto reduce la complejidad de la contraseña, generalmente es mucho más fácil recordar . Ahora quiero mejorarlo generando cadenas que son fáciles de escribir.

QWERTY Keyboard Layout

Por ejemplo, mientras que un novato * nix siempre prefiero distribuciones basadas en Debian RHEL sobre los, la razón principal es la facilidad de escribir yum frente a la facilidad de escribir apt[-get], a modo de prueba por sí mismo.

¿Cómo debo implementar la lógica para generar cadenas que sean fáciles de escribir en los teclados QWERTY?

+1

Definir "más fácil de escribir." Normalmente encuentro que las palabras que puedo escribir más fácilmente son las que puedo pronunciar, por lo que su método funcionaría perfectamente para eso. –

+9

@Alix Axel, en realidad encuentro 'apt' más fácil de escribir que' yum' específicamente porque puedes alternar las manos mientras escribes. – avakar

+0

@BlueRaja: intente escribir 'yum' e intente escribir' apt'; 'yum' debería ser mucho más fácil de escribir (especialmente con solo una mano). Como ejemplos adicionales fáciles de escribir intente escribir 'serverde' o' begreen'; o 'yii' contra' zend'. –

Respuesta

1

Es posible que quieras echar un vistazo a la principles used in the Dvorak keyboard,

Estos principios se aplican en un algoritmo de generación de contraseña sería:

  • Las cartas deben ser mecanografiadas mediante la alteración de las manos.
  • Utilice combinaciones fáciles de escribir. Eche un vistazo al diseño de Dvorak y vea los dígrafos comunes y las posiciones de sus letras.
  • Use solo una letra de la fila inferior, o no. ¡Hazlo al azar!
  • Puede hacer la relación de 2 a 1 (2 letras escritas con la mano derecha a 1 letra escrita con la mano izquierda).
  • Dado que la relación es de 2 a 1, tendrá 2 letras consecutivas tecleadas por la misma mano, por lo que tendrá que asegurarse de que estén escritas desde el exterior del teclado hacia el interior. Este principio se aplica a los dígrafos.

Sé que indican que se encuentra un teclado QWERTY, pero el uso de estos principios en un teclado QWERTY le puede dar muy buenos resultados, como:

ktrd, ogkdo ("máquina de escribir" en Dvorak)

kjg; g; AKD; k (utilizando sólo la fila principal)

pjedoildupsk (justo una contraseña aleatoria siguiendo los principios)

¡Todos los que odian Dvorak, calla!

Espero que esto ayude.

+0

Su sugerencia es similar a la sugerida por @superUntitled, el problema con las manos alternas es que solo puedo usar "ae" o "uio" en mis letras pares (vea mi función original). Como resolverias esto? –

+0

@ Axix Axel: Bueno, mi método es más flexible que el de @superUntitled porque sugiero que uses una proporción de 2 a 1 en lugar de 1 a 1, y no tiene que ser exactamente RRLRRLRRL, mira el azar muestra de contraseña, que sigue mis principios (no las vocales, sin embargo). Es RRLLRRLRRLR que hace posible usar cualquiera de las 5 vocales. –

+0

pjedoildupsk no sigue sus indicaciones. 'u' y' p' se escriben de adentro hacia afuera con la mano derecha, al igual que 'o' y' i'. – ErikE

1

Quizás pueda usar algo de heurística para medir la 'facilidad de tipeo'.

Por ejemplo, considere el costo de mover un dedo cuando vaya al siguiente caracter. Esto puede ser una función de cuánto necesita mover el dedo, en qué dirección, etc.

También podría agregar costos adicionales, cuando se requiera cambiar dedos o manos.

Después de jugar con los costos un poco, es probable que encuentre una solución satisfactoria.

Espero que ayude.

+0

Esa es mi idea, pero estoy teniendo problemas para descubrir cómo implementaría tales heurísticas. –

+0

¿El problema es calcular los pesos o si tiene un problema al escribir el código para calcular los costos de mudarse, etc.? –

+0

@Moron: Averiguar el costo de pasar de char a char + 1 es mi principal preocupación ... –

2

Puede eliminar todos los caracteres que se escriben con el anillo y el dedo meñique (q, w, x, z, p), escupir los caracteres que se escriben con las manos izquierda y derecha y alternar entre estas letras.

+0

+1, Eso es sugerencia bastante buena y fácil de implementar, ¡gracias! –

+0

Intenté implementar esto pero me di cuenta de que al cambiar entre las teclas de dedo izquierda y derecha mi función mnemotécnica pierde un poco el punto, porque solo tendré "ae" o "(y) uio" como vocales. –

+0

aleatoriamente, bit con <50% de probabilidad por clave de mantener el mismo lado, sospecho que alrededor del 25% de posibilidades de intercambio dará lugar a un tipo razonable pero aún distribuido. También asegúrese de que su contraseña generada tenga una probabilidad del 50/50 de comenzar cualquier lado (y consonante/vocal). esto reducirá significativamente su vulnerabilidad a los ataques de fuerza bruta. – ShuggyCoUk

0

Cree una estructura de datos que represente un teclado y codifique la fila, la columna, la mano y el dedo utilizados para escribir cada carácter. Escriba una función que, cuando se presente con un personaje, proporcione una lista de caracteres "fáciles de escribir a continuación", según las reglas flexibles que desarrolle. Podría confiar en otra función que calcula la distancia entre las teclas.

Personalmente, no encuentro que escribir letras con la misma mano dos veces sea lento: solo si una letra anterior usó un dedo que estaba demasiado cerca es difícil. Por ejemplo, XQ es difícil de escribir porque mi mano tiene que moverse hacia arriba para manejar los dedos adyacentes necesarios para escribirlos. Pero no encuentro BQ difícil de escribir en absoluto, porque mientras mi dedo índice todavía está trabajando en la B, mi dedo meñique puede dirigirse a la Q.

También es mucho más fácil escribir AW que QS, porque el dedo anular es más largo y, por lo tanto, cabe naturalmente en la W, mientras que el meñique está en A, en una posición casi de descanso, mientras que QS requiere un estiramiento del meñique y un contragolpe muscular simultáneo y conflictivo del dedo anular.

Si comienza a construir un mapa de cada letra una contra la otra, pronto encontrará una forma razonable de representar varios aspectos de facilidad o dificultad. Generalizando mi ejemplo de XQ/BQ, puede hacer cambios de una fila que requieren una distancia de 2 o más dedos, cambios de 2 filas requieren una distancia de 3 dedos y cambios de 3 filas (los números, tal vez) requieren manos alternativas.

También me doy cuenta de que la distancia ligeramente más larga entre WD e IL que SE y KO también altera la dificultad, debido a la colocación ligeramente irregular de las teclas.

Con algunos análisis (recomiendo usar Excel para "trazar" la dificultad de escritura) Estoy seguro de que se te puede ocurrir un algoritmo que te ayude a construir palabras fáciles de escribir.

Si es posible, intente incluir al menos un número y considere usar espacios también.

1

Gran pregunta - tomando las sugerencias anteriores, he aquí una fórmula para la distancia de la tecla i para tecla J:

Peso = distancia * a + cambiar * b + mismos * c + Shift * d + extraños * e + inicio * f

La distancia es un valor, las demás son 0/1 valores.

Distancia - consigue mediante la superposición de una cuadrícula fina sobre un teclado QWERTY, busca el x, y y calcula la distancia. La distancia tiene un peso positivo. Si la combinación de letras es con el uso de diferentes manos (por ejemplo, aj, sk, wu ...), la distancia es cero.

Interruptor - peso negativo; la conmutación es buena

Igual - aq, qa, az, za usan el mismo dedo. Lo mismo es positivo

Shift - cualquier cosa con un cambio es positivo y muy mal

extraño - no sé $ ~ o es malo porque hay que mirar el teclado.

Inicio - asdfjkl comenzando o terminando. Probablemente negativo & bueno, ya que sus dedos están allí en reposo.

Coeficientes: solo haga que comiencen mientras los valores relativos parezcan razonables. Si REALMENTE desea ser elegante, pida a alguien que escriba varias docenas de conjuntos de números, use un cronómetro y ajuste un modelo de regresión.

Implementación: supongamos que tenemos una contraseña de seis caracteres.

Ahora necesito el valor más bajo para seis caracteres comenzando con cada letra. Imagine una matriz de sus N teclas en una columna. Ahora imagina seis columnas. Su contraseña más corta es la ruta más corta a través de las seis columnas (con ciclos permitidos). Es posible que necesite agregar algo de lógica para eliminar ciclos, pero este debería ser un buen primer paso. (Me estoy volviendo perezoso aquí; probablemente haya una formulación teórica de gráficos que maneje este problema.)

Apuesto a que alguien ha hecho esto antes, especialmente la parte del teclado.

0

Si implementa esto, tenga en cuenta la configuración regional del usuario al determinar el "costo" de pasar de un carácter a otro. Una contraseña fácil de escribir puede volverse bastante engorrosa si el usuario usa una distribución de teclado diferente. Algunas teclas que podrían ser de fácil acceso en el teclado de un idioma podrían no estar disponibles en el teclado de otro idioma sin requerir teclas modificadoras adicionales (cambio, meta, etc.).

Para mantener esta idea universal, recomendaría ignorar qué personaje pertenece a qué tecla y en su lugar tratar las teclas como una matriz con filas y columnas. Cada fila normalmente se compensa con respecto a la anterior en aproximadamente 1/3 del ancho de una clave.Con esto en mente, no debería ser difícil de calcular la distancia entre cualquier par de claves arbitrarias:

# Key at top left corner is {0, 0} 
key1 @ {x1, y1} 
key2 @ {x2, y2} 

xdistance = absolute_value(x2 - x1) 
ydistance = absolute_value(y2 - y1) 

if y1 > y2 
    xdistance += (1/3 * ydistance) 
else 
    xdistance -= (1/3 * ydistance) 

total_distance = square_root(xdistance^2 + ydistance^2) 

generar una serie de puestos clave la reunión de su longitud y la "facilidad de escribir" requisitos, a continuación, utilizar actual del usuario mapa de teclas para volver a mapear esos índices en caracteres.

3

Carpalx tiene una gran cantidad de investigaciones sobre el cálculo de typing effort, que incorpora:

  • distancia de desplazamiento del dedo
  • la mano, los dedos y fila sanciones
  • trayectoria del trazo

El resultado de su investigación es elDiseño de teclado 10, que claims to be better than Dvorak.

Sin embargo, está escrito al revés de lo que desea, su objetivo es encontrar un mejor diseño de teclado basado en la entrada, pero está tratando de encontrar entradas fáciles basadas en el diseño del teclado.

Entonces, aunque no pueda usarlo directamente, pensé que podría encontrarlo interesante (y quién sabe, si su Perl-fu es fuerte, es posible que pueda extraer e invertir el algoritmo, ya que es GPL'd).

+0

Mi Perl'fu no es tan fuerte, pero realmente aprecio el enlace, gracias, –

+1

Esta respuesta es la única respuesta relevante basada en alguna investigación. Todo lo demás es solo conjeturas. Sin una medida objetiva, "más difícil de escribir" simplemente no tiene sentido y es muy subjetivo. –

+0

@Vinko. ¿De qué estás hablando? Esta es probablemente la respuesta más irrelevante. Esta respuesta responde una pregunta totalmente diferente. Entonces, ¿qué pasaría si hicieran una "investigación objetiva" y determinaran un diseño de teclado óptimo basado en un corpus de palabras? ¿Cómo ayuda eso al que pregunta cómo generar contraseñas para escribir mejor en un teclado QWERTY? –

1

Reventé juntos lo siguiente. Es un trabajo de hack pero parece funcionar bastante bien.

<? 
 
function Mnemonic($mnemonic) 
 
{ 
 
    $result = null; 
 
    $charset = array(str_split('@a3e!1i0ou', 1), str_split('#$*bcdfghjklmnpqrstvwxyz', 1)); 
 

 
    $lastchar = ' '; 
 
    for ($i = 1; $i <= $mnemonic; $i++) 
 
    { 
 
     do { 
 
     $char = $charset[$i % 2][array_rand($charset[$i % 2])]; 
 
     } while (!nextkey($lastchar, $char)); 
 
     $result .= $char; 
 
    } 
 

 
    return $result; 
 
} 
 

 
function nextkey($lastchar, $requestchar) 
 
{ 
 
    $map = array(); 
 
    $map[] = '!qaz'; // ll 
 
    $map[] = @#wsx1'; // lr 
 
    $map[] = 'ed23'; // lm 
 
    $map[] = '$%^rtfgcvb456'; // li 
 
    $map[] = '&yhnujm7'; // ri 
 
    $map[] = '*()ik89'; // rm 
 
    $map[] = 'olp,.'; // rr 
 
    $map[] = ';[]'; // rl 
 
    $map[] = '[email protected]#$%^&*()[]'; // special chars, don't follow 
 
    $map[] = 'pbvcnmq'; // consonant clusters, don't follwo 
 

 
    if($lastchar == $requestchar) return true; 
 
    foreach($map as $string) 
 
    if(strpos($string, $requestchar) && strpos($string, $lastchar)) return false; 
 
    return true; 
 
} 
 

 
printf("%s\n", Mnemonic(8)); 
 
?>

Cuestiones relacionadas