Ответ 1
Я думаю, вы неправильно поняли концепцию хэша. Хэш является односторонней функцией. Хуже того, две строки могут генерировать один и тот же хэш.
Нет, это невозможно.
Мне нужно хэшировать некоторые строки, чтобы я мог передавать их в некоторые библиотеки, это прямо, используя вызов String.hashCode.
Однако как только все будет обработано, я хотел бы преобразовать целое число, сгенерированное из hashCode, в значение String. Я мог бы, очевидно, отслеживать значения строки и hashcode где-то в другом месте и выполнять преобразование там, но мне интересно, есть ли что-нибудь в Java, которое сделает это автоматически.
Я думаю, вы неправильно поняли концепцию хэша. Хэш является односторонней функцией. Хуже того, две строки могут генерировать один и тот же хэш.
Нет, это невозможно.
Это невозможно вообще. hashCode
- это то, что можно было бы назвать односторонней функцией.
Кроме того, существует больше строк, чем целых чисел, поэтому существует одно-многое отображение из целых чисел в строки. Строки "0-42L"
и "0-43-"
, например, имеют один и тот же хеш-код. (Демонстрация на ideone.com.)
Однако вы могли бы (в качестве оценки) сохранить хранилища, которые вы передаете в API, и запомнить их хэш-коды следующим образом:
import java.util.*;
public class Main {
public static void main(String[] args) {
// Keep track of the corresponding strings
Map<Integer, String> hashedStrings = new HashMap<Integer, String>();
String str1 = "hello";
String str2 = "world";
// Compute hash-code and remember which string that gave rise to it.
int hc = str1.hashCode();
hashedStrings.put(hc, str1);
apiMethod(hc);
// Get back the string that corresponded to the hc hash code.
String str = hashedStrings.get(hc);
}
}
hashCode()
, как правило, не будет bijection, потому что он обычно не будет injective.
hashCode()
имеет int
как его диапазон. Имеются только 2 ^ 32 различных значения int
, поэтому для любого объекта, где там может быть больше 2 ^ 32 разных (например, подумайте о Long
), вы гарантированы (принцип pigeonhole, что по крайней мере два разных объекта будут иметь один и тот же хэш-код.
Единственная гарантия, которую дает hashCode()
, заключается в том, что если a.equals(b)
, тогда a.hashCode() == b.hashCode()
. Каждый объект, имеющий тот же хэш-код, согласуется с этим.
Вы можете использовать hashCode()
для уникальной идентификации объектов в некоторых очень ограниченных обстоятельствах: у вас должен быть определенный класс, в котором существует не более 2 ^ 32 возможных разных экземпляров (т.е. не более 2 ^ 32 объектов вашего класса, которые попарно таковы, что !a.equals(b)
). В этом случае, пока вы гарантируете, что всякий раз, когда !a.equals(b)
и оба a
и b
являются объектами вашего класса, это a.hashCode() != b.hashCode()
, вы будете иметь биекцию между классами эквивалентности объектов и хеш-кодами. (Например, это может быть сделано для класса Integer
.)
Однако, если вы не находитесь в этом особом случае, вы должны создать уникальный идентификатор другим способом.
Невозможно преобразовать вывод .hashcode()
в исходную форму. Это односторонний процесс.
Вы можете использовать схему base64 encoder, в которой вы будете кодировать данные, использовать их там, где захотите, а затем декодировать их до оригинала форма.