我该怎么做呢?我尝试使用SHA-1和MD5,但输出太长,不符合我的要求,截断也不会使它独一无二。
输入:包含数字的字符串,例如(0302160123456789)
收到的输出:30f2bddc3e2fba9c05d97d04f8da4449
所需输出:范围内的唯一数字(0000000000000000 - FFFFFFFFFFFFFFFF)且长度为16个字符
非常感谢任何帮助/指示。
答案 0 :(得分:1)
你会收到超过FFFFFFFFFFFFFFFF的不同字符串吗?
如果没有那么它就是生成整数的一个简单问题:第一个字符串将在下一个1等时得到0;你只需保留一个字符串列表,并检查是否出现相同的内容。
答案 1 :(得分:1)
您的输入域有多大?如果它大于您的输出域,那么Pigeon Hole principle适用,您无法按定义获得唯一输出。
如果输入域小于或等于输出域,则可以使用阻塞密码提供的Pseudo-Random Permutation (PRP)轻松完成此操作。
16个十六进制的输出相当于8个字节,相当于64位。 DES(和Triple DES)是具有此块大小的分组密码。
以紧凑的方式将输入字符串解析为字节数组。如果输入始终由数字组成,则可以使用Ebbe M. Pedersen的方法
byte[] plaintext = new BigInteger("0302160123456789").toByteArray();
然后,您可以为Triple DES生成一些24字节的随机但固定的密钥,并使用以下代码实例化密码:
Cipher c = Cipher.getInstance("DESede/ECB/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "DESede"));
byte[] ciphertext = c.doFinal(plaintext);
使用某种十六进制转换器来获得所需的表示。
你可以用这个“哈希”数字到36028797018963968。如果你想要更大的数字(最多9223372036854775808),那么你需要使用"DESede/ECB/NoPadding"
并填充一些填充字节。
答案 2 :(得分:0)
您可以使用BigInteger
将您的号码转换为十六进制,如下所示:
String id = new BigInteger("0302160123456789").toString(16);
System.out.println(id);
这给出了:
112d022d2ed15