Я хотел бы применить криптографический хэш к IP-номеру и иметь хэш в наборе символов «abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_».Как преобразовать массив байтов в строку под ограничительным набором символов?
Мои испытания до сих пор:
String ipWithSecret = secret + "123.123.123.123";
byte[] ipBytes = ipWithSecret.getBytes(StandardCharsets.UTF_8);
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] mdBytes = md.digest(ipBytes);
System.out.println("MD5: " + mdBytes);
System.out.println("US ASCII: " + new String(mdBytes, StandardCharsets.US_ASCII));
System.out.println("Hex: " + HexBin.encode(mdBytes));
System.out.println("Base64: " + Base64.encodeBase64String(mdBytes));
System.out.print("Binary: ");
for (byte b : mdBytes) {
System.out.print(Integer.toBinaryString(b & 255 | 256).substring(1));
}
выходы:
MD5: [[email protected]
US ASCII: :???RN???z?}k^?
Hex: 3A8BB1881E524EDFEFE67AFF7D6B5E9D
Base64: OouxiB5STt/v5nr/fWtenQ==
Binary: 00111010100010111011000110001000000111100101001001001110110111111110111111100110011110101111111101111101011010110101111010011101
Кроме шестигранник, ничто не даже отдаленно приемлемым. Мой доступный алфавит намного больше, чем шестнадцатеричный, и, поскольку мне приходится иметь дело с лимитом длины в 16 символов, я хотел бы получить хэш-строку короче.
Любые предложения, как я могу это достичь?
Ответа на этот вопрос Я немного изменил ответ Джона, так что кредит ему принадлежит. Вот мой код, который также обрабатывает столкновения несколько:
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));
Обратите внимание, что IP-адрес всего четыре байта (0-255x4), начните там вместо строки форма. –