【问题标题】:Encode data into user-typed code, like an old game's password-save system将数据编码为用户键入的代码,就像旧游戏的密码保存系统一样
【发布时间】:2012-07-01 05:13:46
【问题描述】:

我尝试搜索这方面的信息,但一定不知道要使用的正确术语...

将信息存储在人类可读和可写密码中的最简单方法是什么,并具有足够的填充以使随机猜测的代码不太可能有效?与 8 位主机游戏的密码保存系统不同。

在我的特定情况下,我希望能够在 Java 1.4.2 下将三个无符号整数(每个最大长度可能约为 20 位)编码为密码,并在 Web 服务器上对其进行解密。我正在考虑添加一个随机或基于日期的值,以尝试使密码独一无二。

代码可以使用数字、混合大小写的字母和一些简单的符号,但应该排除容易混淆的字符,如 1lI 和 O0。由于用户需要输入,显然越短越好。

谢谢!

【问题讨论】:

    标签: java cryptography java1.4 human-readable


    【解决方案1】:
    1. 选择您要使用的字母表。它可以有任意数量的符号,顺序不限。一个示例字母表是 ABCDEFGHJKLMNPQRSTUVWXYZ0123456789,其中包含 34 个符号。
    2. 使用位移位和按位或,或乘法和加法将要保存为单个整数的数据编码。如果您有大约 20 位数据,这应该不是问题。
    3. 以基数 N 编码第 1 步中的整数,其中 N 是字母表中的符号数,然后使用字母表中的符号打印它。
    4. 在末尾添加一个“校验位”。添加所有输出数字 mod N 是一个简单而有用的系统。校验位不是真正的加密货币,不会阻止任何努力 伪造保存代码的人,但它会限制随机选择的代码起作用的机会。如果您的字母表有 34 个符号,那么校验位与随机代码匹配的几率只有 34 分之一。
    5. 要解码,首先验证接收代码中的校验位,然后解码 base-N 表示(反向步骤 3),然后从整数值中提取各个值(反向步骤 2)。

    表示基址n 中的k 位数据加上一个校验位所需的符号数为ceil(k * log(2) / log(n)) + 1,对于k=20 位和n=34 位,它只有5 个。

    【讨论】:

    • 澄清一下,总共大约 60 位(三个 20 位数字)。 - 谢谢!我想这几乎是一个单独的问题,因此如果您不想回答,则无需回答,但是您是否知道在不更改密码长度的情况下混淆密码的任何简单方法,或者我可以在哪里找到有关算法类型的信息适合这样的事情吗?
    • 实际上,我想一些换位可能就足够了。这不是一个高度安全的项目。
    • 我会使用 32 个字符。然后每个编码 5 位,这将您的 20 位数字平均分配。
    【解决方案2】:

    您可以将属性编码为 Base64。唯一的限制是您的属性必须具有固定大小。您可能希望对编码字符串应用 MD5 算法或类似算法。

    使用apache commons codec for java 1.4看看这个snipplet

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

    }

    【讨论】:

    • 投反对票的人能否评论他们为什么不推荐这个?谢谢!
    猜你喜欢
    • 2011-11-03
    • 2013-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 2015-12-14
    • 2019-02-06
    相关资源
    最近更新 更多