Codifique los datos en un código escrito por el usuario, como el sistema de guardado de contraseña de un juego antiguo

Intenté buscar información sobre esto, pero no debo saber los términos correctos para usar...

¿Cuál sería la forma más sencilla de almacenar información en un código de acceso legible y escribible por humanos, con suficiente relleno para que los códigos adivinados al azar sean poco probables de ser válidos? No muy diferente de los sistemas de guardado de contraseñas de los juegos de consola de 8 bits.

En mi caso particular, me gustaría poder codificar tres números enteros sin firmar (con una longitud máxima de aproximadamente 20 bits cada uno) en un código de acceso bajo Java 1.4.2 y descifrarlos en un servidor web. Estaba pensando en agregar también un valor aleatorio o basado en fechas en un intento de hacer que los códigos de acceso sean únicos.

El código podría usar números, letras en mayúsculas y minúsculas y potencialmente algunos símbolos simples, pero probablemente debería excluir caracteres fáciles de confundir como 1lI y O0. Dado que el usuario necesita escribirlo, obviamente, más corto es mejor.

¡Gracias!

preguntado el 01 de julio de 12 a las 06:07

2 Respuestas

  1. Elija el alfabeto que desea utilizar. Puede tener tantos símbolos como desee, en cualquier orden. Un ejemplo de alfabeto sería ABCDEFGHJKLMNPQRSTUVWXYZ0123456789 que contiene 34 símbolos.
  2. Codifique los datos que desea guardar como un solo número entero mediante el uso de cambios de bits y bit a bit o multiplicación y suma. Esto no debería ser un problema si tiene alrededor de 20 bits de datos como dice.
  3. Codifique el número entero del paso 1 en base N, donde N es el número de símbolos en su alfabeto, luego imprímalo usando símbolos del alfabeto.
  4. Agregue un "dígito de control" al final. Agregar todos los dígitos de salida mod N es un sistema simple y útil. Un dígito de control no es una criptografía real y no detendrá a nadie que esté poniendo algo esfuerzo en falsificar un código de guardado, pero limita las posibilidades de que funcione un código elegido al azar. Si su alfabeto tiene 34 símbolos, entonces solo hay una probabilidad de 1 en 34 de que el dígito de control coincida con un código aleatorio.
  5. Para decodificar, primero valide el dígito de verificación en el código recibido, luego decodifique la representación en base N (paso 3 inverso), luego extraiga los valores individuales del valor entero (paso 2 inverso).

El número de símbolos necesarios para representar k bits de datos en la base n más un dígito de control es ceil(k * log(2) / log(n)) + 1, que es sólo 5 para k= 20 bits y n= 34.

Respondido 01 Jul 12, 06:07

Solo aclarando, serían unos 60 bits en total (tres números de 20 bits). - ¡Gracias! Supongo que esta es casi una pregunta separada, por lo que no es necesario que responda si no quiere, pero ¿conoce alguna forma simple de ofuscar el código de acceso sin cambiar su longitud, o dónde podría encontrar información sobre el tipo de algoritmos? que sería adecuado para algo como esto? - Sven Vikingo

En realidad, supongo que alguna transposición podría ser lo suficientemente buena. Este no es un proyecto de alta seguridad. - Sven Vikingo

Usaría 32 caracteres. Luego, cada uno codifica 5 bits, lo que divide sus números de 20 bits de manera uniforme. - erickson

Puede codificar sus propiedades como Base64. La única restricción es que debe tener un tamaño fijo de sus propiedades. Es posible que desee aplicar el algoritmo MD5 o similar a la cadena codificada.

Eche un vistazo a este fragmento usando códec apache commons para java 1.4

public class Base64Encoder {

/**
 * Base64 game properties encoded
 * @param properties list of properties as Strings
 * @return base64 encoded properties
 */
public String encodeProperties(List properties){
    StringBuffer buffer = new StringBuffer();
    Iterator iter = properties.iterator();
    while(iter.hasNext()){
        buffer.append(iter.next().toString());
    }
    return Base64.encodeBase64String(buffer.toString().getBytes());
}

/**
 * Decodes a based64 properties
 * @param propertiesSize list of Integer with each property size
 * @param encodedProperties base64 encoded properties
 * @return List of properties as String
 */
public List decodeProperties(List propertiesSize, String encodedProperties){
    List decodedProperties = new ArrayList();
    Iterator iter = propertiesSize.iterator();
    String decoded = new String(Base64.decodeBase64(encodedProperties.getBytes()));
    int current = 0;
    while(iter.hasNext()){
        Integer propertySize = new Integer(iter.next().toString());
        String property = decoded.substring(current, current + propertySize.intValue());
        decodedProperties.add(property);
        current += propertySize.intValue();
    }
    return decodedProperties;
}

public static void main(String[] args){
    String points = "1450";
    String level = "12";
    String lifes = "2";
    Base64Encoder encoder = new Base64Encoder();
    List properties = new ArrayList();
    properties.add(points);
    properties.add(level);
    properties.add(lifes);
    String encodedProperties = encoder.encodeProperties(properties); //MTQ1MDEyMg==
    System.out.println(encodedProperties);
    List propertiesSize =  new ArrayList();
    propertiesSize.add(Integer.valueOf(points.length()));
    propertiesSize.add(Integer.valueOf(level.length()));
    propertiesSize.add(Integer.valueOf(lifes.length()));
    System.out.println(encoder.decodeProperties(propertiesSize, encodedProperties)); //[1450, 12, 2]
}

}

Respondido 01 Jul 12, 07:07

¿Podría el votante negativo comentar por qué no recomendaría esto? ¡Gracias! - Sven Vikingo

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.