【问题标题】:Generate a 16 digit unique Hexadecimal value from given string of numbers从给定的数字字符串生成一个 16 位唯一的十六进制值
【发布时间】:2016-06-16 01:41:45
【问题描述】:

我该怎么做呢?我尝试使用 SHA-1 和 MD5,但输出对于我的要求来说太长了,并且截断不会使其独一无二。

输入:包含数字的字符串,例如(0302160123456789)

收到的输出:30f2bddc3e2fba9c05d97d04f8da4449

所需输出:范围内的唯一数字 (0000000000000000 - FFFFFFFFFFFFFFFF) 和 16 个字符长

非常感谢任何帮助/指针。

【问题讨论】:

标签: java encryption md5 sha


【解决方案1】:

您的输入域有多大?如果它大于您的输出域,则应用 Pigeon Hole principle,并且您无法根据定义获得唯一输出。

如果输入域小于或等于输出域,那么您可以使用分组密码提供的Pseudo-Random Permutation (PRP) 轻松完成此操作。

16 位十六进制的输出相当于 8 个字节,相当于 64 位。 DES(和三重 DES)是具有此块大小的块密码。

  1. 以紧凑的方式将输入字符串解析为字节数组。如果输入总是由数字组成,您可以使用 Ebbe M. Pedersen 的方法与

    byte[] plaintext = new BigInteger("0302160123456789").toByteArray();
    
  2. 然后您可以为 Triple DES 生成一些随机但固定的 24 字节密钥,并使用以下命令实例化密码:

    Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "DESede"));
    byte[] ciphertext = c.doFinal(plaintext);
    
  3. 使用某种十六进制转换器来获得您想要的表示。

您可以使用它“散列”最多 36028797018963968 的数字。如果您想要更大的数字(最多 9223372036854775808),那么您需要使用 "DESede/ECB/NoPadding" 并用一些填充字节填充自己。

【讨论】:

    【解决方案2】:

    你会收到超过 FFFFFFFFFFFFFFFF 不同的字符串吗?

    如果不是,那么这是一个生成整数的简单问题:第一个字符串将得到 0,接下来是 1,依此类推;您只需保留一个字符串列表并检查是否出现相同的内容。

    【讨论】:

      【解决方案3】:

      您可以像这样使用BigInteger 将您的数字转换为十六进制:

      String id = new BigInteger("0302160123456789").toString(16);
      System.out.println(id);
      

      这给了:

      112d022d2ed15
      

      【讨论】:

        猜你喜欢
        • 2011-08-14
        • 1970-01-01
        • 2020-11-13
        • 2021-06-28
        • 2010-11-22
        • 1970-01-01
        • 1970-01-01
        • 2017-01-01
        • 2023-03-08
        相关资源
        最近更新 更多