Преобразуйте строку в хэш, а затем измените строку позже.

Мне нужно хэшировать некоторые строки, чтобы я мог передавать их в некоторые библиотеки, это прямо, используя вызов String.hashCode.

Однако как только все будет обработано, я хотел бы преобразовать целое число, сгенерированное из hashCode, в значение String. Я мог бы, очевидно, отслеживать значения строки и hashcode где-то в другом месте и выполнять преобразование там, но мне интересно, есть ли что-нибудь в Java, которое сделает это автоматически.

Ответ 1

Я думаю, вы неправильно поняли концепцию хэша. Хэш является односторонней функцией. Хуже того, две строки могут генерировать один и тот же хэш.

Нет, это невозможно.

Ответ 2

Это невозможно вообще. 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);
    }
}

Ответ 3

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.)

Однако, если вы не находитесь в этом особом случае, вы должны создать уникальный идентификатор другим способом.

Ответ 4

Невозможно преобразовать вывод .hashcode() в исходную форму. Это односторонний процесс.

Вы можете использовать схему base64 encoder, в которой вы будете кодировать данные, использовать их там, где захотите, а затем декодировать их до оригинала форма.