Среда, 17.06.2026, 16:33
Приветствую Вас Гость | RSS
Главная | Каталог статей | Регистрация | Вход
Меню
Форма входа
Категории раздела
Интернет статьи [9]
статьи [105]
Поиск
Мой сайт
Главная » Статьи » статьи

Unhashing String
Мои рабочие по струнам в осуществлении переключатель имеет получили поменялись обратно дюйма осуществление следующих перевода стратегии, изложенной в строке переключателя в предложении: найти идеальное хэш-функция для ввода строки и семантически заменить case "Foo": в case hash("Foo"): (наряду с некоторыми дополнительными проверками и логике), где hash("Foo") рассчитывается в качестве постоянного компилятором.

При таком подходе, написать регрессионные тесты это полезно иметь возможность построить строку с заданной хеш-значения силы столкновения и проверить альтернативные логики, которая привела меня писать "unhash" метод, чтобы создать строку с данного хэш-код:
  / **
    * Возвращает строку с хеш равный аргументу.
    * @ Вернуть строку с хеш равный аргументу.
    * /
   общественности статической unhash String (Int цели) (
      Ответ StringBuilder = New StringBuilder ();
      если (целевая <0) (
          / / Строка с хэш Integer.MIN_VALUE, 0x80000000
          answer.append ( "\ u0915 \ u0009 \ u001e \ u000C \ u0002");

          если (цель == Integer.MIN_VALUE)
              возвращение answer.toString ();
          / / Поиск цели без знака бит
          TARGET = целевой & Integer.MAX_VALUE;
      )
        
      unhash0 (ответ, цели);
      возвращение answer.toString ();
  )

  частные статического unhash0 Void (StringBuilder частичное, Int цели) (
      Int Div = Target / 31;
      Int бэр = целевую 31%;

      если (DIV <= Character.MAX_VALUE) (
          если (DIV! = 0)
              partial.append ((Char) DIV);
          partial.append ((символ) бэр);
      () Другое
          unhash0 (частичный, DIV);
          partial.append ((символ) бэр);
      )
  )

Алгоритм хэширования строки умножает старой хеш-значение от 31 и добавляет в целое значение следующего характера:
  H = 0;
  для (INT I = 0; i <Len; I + +) (
      H = 31 * H + Val [Off + +];
  )

Unhash работ методом обратного, для неотрицательных значений обрабатывается unhash0 разделите целевой показатель до 31:

если частное меньше Character.MAX_VALUE частное и остаток может быть полностью захватили использование не более двух знаков.

если частное больше или равна Character.MAX_VALUE unhash фактор, и добавьте к этому строка символов для остальных.

С некоторыми дополнительными заботами, отрицательные значения можем использовать тот же процесс. Главное наблюдение, что если строка хэши для Integer.MIN_VALUE (0x80000000), последующие кратные 31 (0x1F) не изменить результат, поскольку
0x1F = 0x80000000 × 0xf80000000
которая вновь 0x80000000, когда ограничиваются int диапазоне. Таким образом, знаковый разряд может быть установлен, а затем оставшиеся биты обрабатываются как если цель была положительной.

Использование нескольких минутах машинного времени, я проверил unhash метода на всех целых значений и он всегда возвращался правильные строки. Когда доступно, исчерпывающего тестирования приятно прост и обнадеживает! Сгенерирована строки относительно коротким; как показано в таблице ниже, не связанных с отрицательными значениями средней длиной чуть более четырех символов.
Распределение String Длины Unhashed неотрицательные значения Длина     Частоты
1     31
2     2.031.585
3     60.948.480
4     1.889.402.880
5     195.100.672
Всего     2.147.483.648


Unhash 0 могут быть специальные обсаженной возвращать пустую строку нулевой длины, а не длина одной строки \u0000 характер, но это не является необходимым для целей под рукой. Аналогичным образом, создавая несколько коротких строк для отрицательных значений хэш может быть возможным, но дальнейшее расследование не нужно просто уметь генерировать столкновений. Как стоит, unhash вернет строку, длина которых не превышает десяти, пяти символов для негативных бит знака и в большинстве еще пять символов для не-знак биты.
(2009-09-10 11:50:30.0) Permalink Комментарии [4]

Trackback URL: http://blogs.sun.com/darcy/entry/string_unhashing
Комментарии:


Nicely окольными ... B ^>

Теперь, вы бы созерцать думал о возможной оценке в свое время ... обобщаю это работа над CharSequence вместо этого?

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

Возможно, вам придется явного вычисления хэш (и, тем самым теряя кеширования рамках String) для не-String значением переключателя, чтобы вы получили хеш, который вы ожидали, но которые могут быть масштабы дополнительных усилий.

Rgds

Дэймон

Написал Дэймон Харт-Дэвис 10 сентября 2009 года в 12:26 вечера PDT #

@ Дэймон,

Строки в переключатель не будет обобщать и произвольного CharSequences поскольку CharSequence объекты не обязательно являются неизменными, и их стоимость может таким образом, изменение в период между хеш было принято, и, когда значение было использовано внутри соответствующего дела (с). Кроме того, точное поведение равных и HashCode методов произвольных CharSequences не определены.

Включение myCharSequence.toString () будет работать, но Строка должна быть создана конечно.

Написал Джо Дарси 10 сентября 2009 года в 12:53 вечера PDT #

Привет,

Я слышал, что вы говорите о неизменности, но предполагая этикетки (или вести себя как "ИФ") постоянная Строковые значения то все что вам потребуется сделать для Non-String CharSequence переключатель значения вычислим его хэш с алгоритмом, что строка использует на Charat () на величину, не называя HashCode значение's (), как вы предполагают, избегая создания String. Также и вы, мог бы затем использовать Charat ()-мудрый равна () замена. Если вы беспокоились о сохранении JVM и струнного хэш осущ / Algo в шаге то это будет большой проблемой.

И если пользователи переключателя глупости мутировать их стоимости (например, в другом потоке) при переключении на него, ну ... Может быть, необходимо каким-то изменчивость Дарвин награда за плохой кодирования? B ^>

Rgds

Дэймон

Написал Дэймон Харт-Дэвис 10 сентября, 2009 в 02:13 PM PDT #

Номера рекурсивная версия для вас.

общественности статической unhash String (Int хеш) (
долгое H = хэш & ((1L <<32) - 1);
StringBuilder SB = новый StringBuilder ();
а (Н> 0) (
sb.Append ((символ) (H% 31));
H / = 31;
)
возвращение sb.reverse (). ToString ();
)
Категория: статьи | Добавил: Aleksei (15.10.2009)
Просмотров: 404 | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *:
экология. Экологический портал. Картинки, обои, скриншоты из игр, программыCopyright Aleksei Kraev 11Б © 2026