UUID одинаково из разных строк - программирование
Подтвердить что ты не робот

UUID одинаково из разных строк

У меня две разные строки, но после разбора в UUID это похоже на то же самое

public static void main(String[] args) {
    try {
        UUID t1 = UUID.fromString("38e1036d-7527-42a3-98ca-f2f19d3155db");
        UUID t2 = UUID.fromString("123438e1036d-7527-42a3-98ca-f2f19d3155db");
        System.out.println(t1.toString().equals(t2.toString()));
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Любая идея, почему это так?

4b9b3361

Ответ 1

"123438e1036d-7527-42a3-98ca-f2f19d3155db"

Это не UUID. Это конкатенированная строка "1234" и UUID. Проблема здесь в том, что анализатор должен был сказать вам это, выбросив исключение. Вместо этого он изо всех сил пытается найти UUID где-то там.

Как только вы извлекаете UUID из вашей конкатенированной строки, он идентичен первому UUID, который является правильным результатом, который вы наблюдаете.

Мы можем проанализировать парсер (благодаря @tim-biegeleisen для предоставления ссылки):

public static UUID fromString(String name) {
    String[] components = name.split("-");
    if (components.length != 5)
        throw new IllegalArgumentException("Invalid UUID string: "+name);
    for (int i=0; i<5; i++)
        components[i] = "0x"+components[i];

    long mostSigBits = Long.decode(components[0]).longValue();
    mostSigBits <<= 16;
    mostSigBits |= Long.decode(components[1]).longValue();
    mostSigBits <<= 16;
    mostSigBits |= Long.decode(components[2]).longValue();

    long leastSigBits = Long.decode(components[3]).longValue();
    leastSigBits <<= 48;
    leastSigBits |= Long.decode(components[4]).longValue();

    return new UUID(mostSigBits, leastSigBits);
}

Как мы видим, нет проверки, кроме подсчета числа групп, ограниченных дефисом. Он просто берет эти группы, а затем перемещает их в позиции. Вы добавили дополнительные символы перед первой группой, что является наиболее важной частью. Сначала он разбирается и запоминается, а затем он перемещается вверх и снова вверх, пока он не занимает самую значительную часть. Теперь все биты, которые были дальше слева, чем предполагалось, вытесняются из предела long, поэтому они полностью игнорируются.

Ответ 2

A UUID хранит 128 бит данных. Если вы дадите больше, они не смогут их хранить. Я удивлен, что это не дает вам ошибки, но не удивляет, что в противном случае обрезает более высокие бит.

int i = 0x38e1036d;
int j = (int) 0x123438e1036dL;
i == j;

Ответ 3

Смещение бит второго компонента "7527" устраняет эффект внесенной вами модификации в первый компонент "123438e1036d", в результате чего генерируется тот же самый UUID.

Обработка первого компонента сама по себе различна, но этот эффект теряется при смещении второго компонента uuid.

Ответ 4

Это потому, что он проверяет справа налево и занимает всего 32 символа как UUID и удаляет другие. как только 32 символа в порядке, он не заботится о других, так как он реализует интерфейс Serializable.

public final class UUID
  extends Object
  implements Serializable, Comparable<UUID>

1234 обрезается от вас 2-м UUID.

Вот его код, он помогает намного лучше

 public static UUID More ...fromString(String name) {
    String[] components = name.split("-");
    if (components.length != 5)
        throw new IllegalArgumentException("Invalid UUID string: "+name);
    for (int i=0; i<5; i++)
        components[i] = "0x"+components[i];

    long mostSigBits = Long.decode(components[0]).longValue();
    mostSigBits <<= 16;
    mostSigBits |= Long.decode(components[1]).longValue();
    mostSigBits <<= 16;
    mostSigBits |= Long.decode(components[2]).longValue();

    long leastSigBits = Long.decode(components[3]).longValue();
    leastSigBits <<= 48;
    leastSigBits |= Long.decode(components[4]).longValue();

    return new UUID(mostSigBits, leastSigBits);
    }

Ответ 5

Это известная ошибка в Java 8, о которой сообщалось в июне 2016 года: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8159339

См. также http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8165199 (сообщается в августе 2016 года):

4d4d8f3b-3b81-44f3-968d-d1c1a48b4ac8 - действительный UUID.

4d4d8f-3b3b81-44f3-968d-d1c1a48b4ac8 нет (перемещен первый штрих два символа влево)

Вызов UUID:: fromString() с недопустимым приводит к UUID, представляющему 004d4dbf-3b81-44f3-968d-d1c1a48b4ac8.