character - significa - que es una señal inequívoca
Conjunto de letras y números de apariencia inequívoca para la entrada del usuario (6)
¿Existe un subconjunto de alfanuméricos que sea más fácil de leer? En particular, ¿hay un subconjunto que tenga menos caracteres que sean visualmente ambiguos y al eliminar (o igualar) ciertos caracteres reducimos el error humano?
Sé que "visualmente ambiguo" es un tanto torpe de expresión, pero es bastante evidente que D, O y 0 son todos similares, y 1 y I también son similares. Me gustaría maximizar el tamaño del conjunto de números alfa, pero minimizar el número de caracteres que probablemente se malinterpretarán.
El único precedente que conozco para tal conjunto es el sistema de códigos postales de Canadá que elimina las letras D, F, I, O, Q y U, y ese subconjunto se creó para ayudar al proceso de OCR del sistema postal.
Mi idea inicial es usar solo letras mayúsculas y números de la siguiente manera:
A B = 8 C = G D = 0 = O = Q E = F H I = J = L = T = 1 = 7 K = X M N P R S = 5 U = V = Y W Z = 2 3 4 6 9
Este problema puede ser difícil de separar de la cara del tipo dado. El carácter distintivo de los caracteres en el tipo de letra elegido podría afectar significativamente la posible ambigüedad visual de cualquiera de los dos caracteres, pero espero que en la mayoría de los tipos de letra modernos los caracteres anteriores que se equiparan tengan un aspecto lo suficientemente similar como para justificar su comparación.
Estaría agradecido por los pensamientos sobre lo anterior. ¿Son adecuadas las ecuaciones anteriores o quizás hay más caracteres que deberían equipararse? ¿Serían más adecuados los caracteres en minúscula?
Aquí hay un poco de python que escribí para codificar y decodificar números enteros usando el sistema de caracteres descrito anteriormente.
def base20encode(i):
"""Convert integer into base20 string of unambiguous characters."""
if not isinstance(i, int):
raise TypeError(''This function must be called on an integer.'')
chars, s = ''012345689ACEHKMNPRUW'', ''''
while i > 0:
i, remainder = divmod(i, 20)
s = chars[remainder] + s
return s
def base20decode(s):
"""Convert string to unambiguous chars and then return integer from resultant base20"""
if not isinstance(s, str):
raise TypeError(''This function must be called on a string.'')
s = s.translate(bytes.maketrans(b''BGDOQFIJLT7KSVYZ'', b''8C000E11111X5UU2''))
chars, i, exponent = ''012345689ACEHKMNPRUW'', 0, 1
for number in s[::-1]:
i += chars.index(number) * exponent
exponent *= 20
return i
base20decode(base20encode(10))
Depende de cuán grande quieras que sea tu set. Por ejemplo, solo el conjunto {0, 1} probablemente funcionará bien. Del mismo modo el conjunto de dígitos solamente. Pero probablemente desee un conjunto que sea aproximadamente la mitad del tamaño del conjunto original de caracteres.
No he hecho esto, pero he aquí una sugerencia. Elija una fuente, elija un conjunto inicial de caracteres y escriba un código para hacer lo siguiente. Dibuje cada carácter para que quepa en un cuadrado n-por-n de píxeles blancos y negros, para n = 1 a (digamos) 10. Corte cualquier fila y columna completamente blanca del borde, ya que solo estamos interesados en el zona negra Eso te da una lista de 10 códigos para cada personaje. Mida la distancia entre cualquiera de los dos caracteres por cuántos de estos códigos difieren. Calcule qué distancia es aceptable para su aplicación. Luego haz una búsqueda de fuerza bruta para un conjunto de caracteres que están tan alejados.
Básicamente, use un guión para simular entrecerrar los ojos en los caracteres y ver cuáles aún puede distinguirlos.
Esto sería un problema general en OCR. Por lo tanto, para la solución de extremo a extremo, donde se controla la codificación OCR, se han desarrollado fuentes especializadas para resolver el problema de "ambigüedad visual" que mencionas. Ver: http://en.wikipedia.org/wiki/OCR-A_font
como información adicional: es posible que desee saber acerca de la codificación Base32, en donde el símbolo para el dígito ''1'' no se usa, ya que puede ''confundir'' a los usuarios con el símbolo para el alfabeto ''l''.
Lo que busca es un código de Computador Humano no ambiguo y eficiente. Lo que recomiendo es codificar todos los datos con palabras literales (significativas), nombres en particular.
He estado desarrollando un software para hacer eso, y de manera más eficiente. Yo lo llamo WCode .
Técnicamente es solo la codificación Base-1024, en la que usas palabras en lugar de símbolos.
Aquí están los enlaces:
Presentación: https://docs.google.com/presentation/d/1sYiXCWIYAWpKAahrGFZ2p5zJX8uMxPccu-oaGOajrGA/edit
Documentación: https://docs.google.com/folder/d/0B0pxLafSqCjKOWhYSFFGOHd1a2c/edit
Proyecto: https://github.com/San13/WCode (Por favor, espere mientras estoy subiendo ...)
Necesitaba un reemplazo para hexadecimal (base 16) por razones similares (por ejemplo, para codificar una clave, etc.), lo mejor que puedo encontrar es el siguiente conjunto de 16 caracteres, que puede usarse como reemplazo del hexadecimal:
0 1 2 3 4 5 6 7 8 9 A B C D E F Hexadecimal
H M N 3 4 P 6 7 R 9 T W C X Y F Replacement
En el conjunto de reemplazo, consideramos lo siguiente:
Todos los caracteres utilizados tienen características distintivas principales que solo se omitirían en una fuente realmente horrible.
Se omiten las vocales AEIOU para evitar la ortografía accidental de las palabras.
Los conjuntos de caracteres que potencialmente podrían ser muy similares o idénticos en algunas fuentes se evitan por completo (ninguno de los caracteres en ningún conjunto se utiliza en absoluto):
0 O D Q
1 I L J
8 B
5 S
2 Z
Al evitar estos caracteres por completo, la esperanza es que el usuario ingrese los caracteres correctos, en lugar de intentar corregir los caracteres ingresados incorrectamente.
Para conjuntos de caracteres menos similares pero potencialmente confusos, solo usamos un carácter en cada conjunto, con suerte el más distintivo:
Y U V
Aquí se usa Y, ya que siempre tiene la sección vertical inferior, y un serif en fuentes serif
C G
Aquí se usa C, ya que parece menos probable que una C se ingrese como G, que al revés
X K
Aquí se usa X, ya que es más consistente en la mayoría de las fuentes
F E
Aquí se usa F, ya que no es una vocal
En el caso de estos conjuntos similares, la entrada de cualquier carácter en el conjunto podría convertirse automáticamente al que realmente se usa (el primero que se enumera en cada conjunto). Tenga en cuenta que E no se debe convertir automáticamente a F si se puede utilizar la entrada hexadecimal (ver más abajo).
Tenga en cuenta que todavía hay letras con un sonido similar en el conjunto de reemplazo, esto es bastante inevitable. Cuando se lee en voz alta, se debe usar un alfabeto fonético.
Cuando los caracteres que también están presentes en el hexadecimal estándar se usan en el conjunto de reemplazo, se usan para el mismo valor de base-16. En teoría, se podrían admitir entradas mixtas de caracteres hexadecimales y de reemplazo, siempre que E no se convierta automáticamente a F.
Dado que esto es solo un reemplazo de carácter, debería ser fácil de convertir a / desde hexadecimal.
La letra mayúscula parece mejor para la forma "canónica" de salida, aunque la letra minúscula también parece razonable, a excepción de "h" y "n", que aún deberían ser relativamente claras en la mayoría de las fuentes:
h m n 3 4 p 6 7 r 9 t w c x y f
Por supuesto, la entrada puede ser insensible a mayúsculas y minúsculas.
Hay varios sistemas similares para la base 32, consulte http://en.wikipedia.org/wiki/Base32 Sin embargo, obviamente estos deben introducir caracteres de aspecto más similar, a cambio de un 25% más de información por personaje.
Aparentemente, el siguiente conjunto también se usó para las claves de producto de Windows en la base 24, pero nuevamente tiene caracteres de aspecto similar:
B C D F G H J K M P Q R T V W X Y 2 3 4 6 7 8 9
Principalmente inspirándome en este hilo ux , mencionado por @rwb,
- Several programs usan cosas similares. La lista en su publicación parece ser muy similar a las utilizadas en estos programas, y creo que debería ser suficiente para la mayoría de los propósitos. Puede agregar siempre agregar redundancia (corrección de errores) para "perdonar" errores menores; sin embargo, esto requerirá que usted separe sus códigos (vea la distancia de Hamming ).
- No hay referencias al método particular utilizado para derivar las listas, excepto prueba y error con humanos (lo cual es ideal para no-ocr: sus usuarios son humanos)
- Puede tener sentido utilizar la agrupación de caracteres (por ejemplo, grupos de 5) para aumentar el contexto ("primer carácter en el segundo de los 5 grupos")
- La ambigüedad se puede eliminar mediante el uso de sustantivos completos (de un diccionario con pocos parecidos; la distancia de edición de palabras puede ser útil aquí) en lugar de los caracteres. La gente puede confundir "1" con "i", pero pocos confundirán "uno" con "hielo".
- Otra opción es convertir su código en una palabra (falsa) que se pueda leer en voz alta. Un modelo de Markov puede ayudarte allí.