我想将加密哈希值应用于IP号码,并将哈希值放在字符集中,并且#34; abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 _"。
到目前为止我的试验:
MD5: [B@6d6f6e28
US ASCII: :???RN???z?}k^?
Hex: 3A8BB1881E524EDFEFE67AFF7D6B5E9D
Base64: OouxiB5STt/v5nr/fWtenQ==
Binary: 00111010100010111011000110001000000111100101001001001110110111111110111111100110011110101111111101111101011010110101111010011101
输出:
String secret = "secret"; //config file, do not store in code
Set existingMdBase64Alt = new HashSet(Arrays.asList("OouxiB5STt_v5nr_", "ouxiB5STt_v5nr_f"));
String ipWithSecret = secret + "123.123.123.123";
byte[] ipBytes = ipWithSecret.getBytes(StandardCharsets.UTF_8);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] mdBytes = md.digest(ipBytes);
String mdBase64 = Base64.encodeBase64String(mdBytes);
String mdBase64Alt = mdBase64.replace("+","_").replace("/","_" );
System.out.println("Debug: " + mdBase64Alt.substring(0, 16));
while (mdBase64Alt.length() > 16 && existingMdBase64Alt.contains(mdBase64Alt.substring(0, 16))){
mdBase64Alt = mdBase64Alt.substring(1);
System.out.println("Debug: " + mdBase64Alt.substring(0, 16));
}
System.out.println("Final: " + mdBase64Alt.substring(0, 16));
除了十六进制之外,甚至没有任何东西可以接受。我的可用字母比十六进制字母大得多,因为我必须处理16个字符的长度限制,所以我希望哈希字符串更短。
我有什么建议可以实现这个目标吗?
答案 我稍微修改了John的答案,所以很有信心。这里的代码也有点处理冲突:
<p><br data-mce-bogus="1"></p>
答案 0 :(得分:4)
一般情况下,不要重新发明轮子:使用base64。这是一般的“短于十六进制,但仍然可打印的ASCII”解决方案。有各种base64选项可供选择,具体取决于您使用的Java版本等。如果您使用的核心框架中没有任何内容,我喜欢iharder.net public domain implementation。
但是,这不是真的会帮助你。 MD5哈希值是16个字节 - 所以除非你有256个字符可供使用(用一个字符表示每个字节),你最终会得到超过16个字符,这只是因为你的信息量很大重新尝试代表。
正如评论中所述,IPv4地址只有4个字节。坦率地说,散列不会掩盖它,因为散列整个地址空间显然是可行的......