Хеш-коллизия: «НЕТ» означает «ДА»


63

Этот Code Golf был вдохновлен недавней статьей Daily WTF, « Вы не можете справиться с истиной»! , который показывает сравнение строк, записанное в виде:

String yes = "YES";
if ((delay.hashCode()) == yes.hashCode())

Представьте себе проблему, которую это вызвало бы для команды Стива, если бы String.hashCodeметод Java был реализован таким образом "YES".hashCode() == "NO".hashCode(). Итак, проблема, которую я предлагаю здесь:

Напишите как можно меньше символов хеш-функции (я ее назову h) со строковым параметром и целочисленным возвращаемым значением, таким, что h("YES")равно h("NO").

Конечно, это было бы тривиально сделать с функцией like def h(s): return 0, которая создает хеш-коллизию для каждой строки. Чтобы сделать этот вызов более интересным, вы должны соблюдать следующее дополнительное правило:

Из других 18 277 возможных строк , состоящих из трех или менее заглавных букв (ASCII ^[A-Z]{0,3}$), не должна быть ни одного хэша столкновения.

Пояснение (на это указывает Heiko Oberdiek): входная строка может содержать символы, отличные от A-Z, и ваш код должен иметь возможность хешировать произвольные строки. (Тем не менее, вы можете предположить, что ввод является символьной строкой, а не нулевым указателем или объектом какого-либо другого типа данных.) Однако, не имеет значения, какое возвращаемое значение для строк, которые не совпадают ^[A-Z]{0,3}$, если это целое число

Кроме того, чтобы скрыть намерение этой функции:

Ваш код не должен содержать буквы «Y», «E», «S», «N» или «O» (в верхнем или нижнем регистре) внутри символьных или строковых литералов.

Конечно, это ограничение не распространяется на ключевые слова языка, поэтому else, returnи т.д. все в порядке.


4
Это вроде не помогает, что мы все еще можем использовать числовые значения ASCII YESNOдля проверки этого конкретного исключения.
Джо З.

1
Читая статью, нельзя не вспомнить комикс «по причинам»: treewordphrase.com/pardonme.gif
Антонио Раганьин,

Ответы:


7

GolfScript: 19 символов (24 символа для именованной функции)

26base.2107=59934*+

Это тело функции. Присвоение его именованной функции hзанимает еще пять символов:

{26base.2107=59934*+}:h;

(Последняя точка с запятой может быть опущена, если вы не против оставить копию кода в стеке.)

Ядро хэш - функции является 26base, которая вычисляет сумму (26 п - к · к ; к = 1 .. п ), где п есть число символов во входных данных и к обозначает ASCII код K -го Введите символ Для входных данных, состоящих из прописных букв ASCII, это хеш-функция без столкновений. Остальная часть кода сравнивает результат с 2107 (хэш-кодом ) и, если они равны, добавляет 59934, чтобы получить 2701 + 59934 = 62041, хеш-код .NOYES

Например вывод, посмотрите эту онлайн-демонстрацию с тестовыми примерами .


Как вы это проверили? Я только что нашел кучу столкновений . Пример: h('DXP') == h('KK') == 65884.
nneonneo

(Python эквивалент того , что вы написали, для моих целей тестирования: lambda w:sum(ord(c)*26**i for i,c in enumerate(reversed(w*9)))%102983)
nneonneo

@nneonneo: Очевидно, недостаточно хорошо. Я подумал, что сгенерировал полный набор трехбуквенных входов, хэшировал их все и проверил, что набор хэшей имеет на один элемент меньше, чем набор входов. Ясно, что у моего тестового жгута где-то была ошибка. :-( Я вернусь к исходной 19-символьной версии до тех пор, пока не смогу исправить более короткую версию.
Ильмари Каронен

54

32-битный Python 2.x (19)

hash(w*9)%537105043

RSA использует модуль полупростой передачи, и это делает его безопасным, поэтому использование его с моим алгоритмом хеширования, несомненно, сделает его еще лучше! 1

Это чисто математическая функция, она работает для всех строк (черт возьми, работает для любого хэшируемого объекта Python) и не содержит никаких условных или специальных символов! 32-битный Python обычно вызывается так же, как и python-32в большинстве систем, в которых установлено 2 .

Я проверил это, и он возвращает 18 278 различных значений для 18 279 строк, состоящих из 3 букв или менее. Назначение этой функции занимает еще 11 байтов:

h=lambda w:hash(w*9)%537105043

и h('YES') == h('NO') == 188338253.

64-битный Python 2.x (19)

hash(w*2)%105706823

Та же сделка, что и выше.


Чтобы придумать эти цифры, было использовано немного модульной математики. Я искал функцию fи модуль n, чтобы hash(f('YES')) % n == hash(f('NO')) % n. Это эквивалентно тестированию, которое nделит d = hash(f('YES')) - hash(f('NO')), то есть мы должны только проверить факторы dдля подходящих значений n.

В идеале nэто должно быть около 20000 ** 2, чтобы уменьшить вероятность столкновения с парадоксом дня рождения. Нахождение подходящего nоказывается методом проб и ошибок, играя со всеми факторами d(обычно их не так много) и различными вариантами выбора функции f. Обратите внимание, что метод проб и ошибок необходим только потому, что я хотел сделать nкак можно меньше (для игры в гольф). Если бы это не было требованием, я мог бы просто выбрать в dкачестве моего модуля, который обычно достаточно велик.

Также обратите внимание, что вы не можете использовать этот трюк, используя just f(s) = s(функцию тождества), потому что крайний правый символ строки имеет по существу линейную связь (фактически XORсвязь) с конечным хешем (другие символы вносят гораздо более нелинейный вклад ). Следовательно, повторение строки гарантирует, что различия между строками усиливаются, чтобы исключить эффект изменения только самого правого символа.


1 Это чепуха.
2 Хэширование строки Python зависит от основной версии (2 против 3) и битности (32-разрядная или 64-разрядная). Это не зависит от платформы AFAIK.


Вы получили мой голос. : D
cjfaure

К сожалению, это не работает в последних версиях Python из-за новой функции рандомизации хэшей.
2014 г.

@ dan04: Странно, я думал, что уточнил, что это только для Python 2.x. Я отредактировал это снова.
nneonneo

Могу ли я узнать, как вы нашли эти магические числа? Я вижу, hash('YES'*9)имеет 34876679как фактор, а hash('NO'*9)имеет 34876679+537105043как фактор. Но как вы узнали, что 537105043это хороший модуль? т.е. он не совершал других столкновений?
Антонио Раганьин

@AntonioRagagnin: добавил это к ответу.
nneonneo

38

Perl, 53 49 40 байт

sub h{hex(unpack H6,pop)-20047||5830404}

Контрольная работа:

h('YES') = 5830404
h('NO')  = 5830404
Keys:   18279
Values: 18278

Хеш-значения для YESи NOодинаковы, и есть 18279 строк^[A-Z]{0,3}$ , которые не содержат коллизий, кроме единственной коллизии для YESи NO.

Ungolfed:

sub h {
    hex(unpack("H6", pop())) - 20047 || 5830404;
    # The argument is the first and only element in the argument array @_.
    # "pop" gets the argument from array @_ (from the end).
    # The first three bytes of the argument or less, if the argument
    # is shorter, are converted to a hex string, examples:
    #   "YES" -> "594553"
    #   "NO"  -> "4e4f"
    # Then the hex string is converted to a number by function "hex":
    #   0x594553 = 5850451
    #   0x4e4f   =   20047
    # The value for "NO" is subtracted, examples:
    #   case "YES": 5850451 - 20047 = 5830404
    #   case "NO":    20047 - 20047 =       0
    # If the argument is "NO", the subtraction is zero, therefore
    # 5830404 is returned, the result of "YES".
}

# Test
my %cache;
sub addcache ($) {$cache{$_[0]} = h($_[0])}

# Check entries 'YES' and 'NO'
addcache 'YES';
addcache 'NO';
print "h('YES') = $cache{'YES'}\n";
print "h('NO')  = $cache{'NO'}\n";

# Fill cache with all strings /^[A-Z]{0-3}$/
addcache '';
for my $one (A..Z) {
    addcache $one;
    for (A..Z) {
        my $two = "$one$_";
        addcache $two;
        for (A..Z) {
            my $three = "$two$_";
            addcache $three;
        }
    }
}
# Compare number of keys with number of unique values
my $keys = keys %cache;
my %hash;
@hash{values %cache} = 1 x $keys;
$values = keys %hash;
print "Keys:   $keys\n";
print "Values: $values\n";

Старая версия, 49 байт

Поскольку новый алгоритм немного отличается, я сохраняю старую версию.

sub h{($_=unpack V,pop."\0"x4)==20302?5457241:$_}

Контрольная работа:

h('YES') = 5457241
h('NO')  = 5457241
Keys:   18279
Values: 18278

Ungolfed:

sub h {
    $_ = unpack('V', pop() . ($" x 4);
        # pop():  gets the argument (we have only one).
        # $" x 4: generates the string "    " (four spaces);
        #   adding the four spaces ensures that the string is long
        #   enough for unpack's template "V".
        # unpack('V', ...): takes the first four bytes as
        #   unsigned long 32-bit integer in little-endian ("VAX") order.
    $_ == 20302 ? 5457241 : $_;
        # If the hash code would be "NO", return the value for "YES".
}

Редактирование:

  • Использование в "\0"качестве байта заполнения экономит 4 байта по сравнению с $".

Откуда 5457241и 20047откуда? Как вы рассчитываете эти числа? Заранее спасибо.
AL

@ n.1: YESв шестнадцатеричном виде есть 594553. 0x594553 = 5850451. NOв гексе есть 4e4f. 0x4e4f = 20047.
nneonneo

7

Python: 63

Невероятно слабое решение:

def h(s):
 try:r=int(s,36)
 except:r=0
 return(r,44596)[r==852]

Он работает, интерпретируя алфавитно-цифровые строки как числа base-36 и возвращая 0 для всего остального. Существует явный особый случай, чтобы проверить возвращаемое значение 852 (НЕТ) и вернуть вместо него 44596 (ДА).


3
Если я не пойму неправильно: это кодовый гольф, вы можете предполагать, что ввод точный. Можно угробить try:и всю третью линию. Вы также можете сохранить несколько укусов, поместив каждую логическую строку в одну и ту же фактическую строку, разделенную точкой с запятой ( def h(s):r=int(s,36);return(r,44596)[r==852])
подземный

1
@undergroundmonorail: строковый параметр для хеш-функции не ограничен в вопросе. Для определенного класса строк (до трех заглавных букв) существует ограничение относительно возвращаемых значений хеш-функции. Однако не имеет значения, что возвращается для других строк, если возвращаемое значение является целым числом.
Хайко Обердик

3
Мне нравится там логическое индексирование вашего массива
kratenko

6

Pure Bash, 29 байт (функциональное тело)

h()(echo $[n=36#$1,n-852?n:44596])

Это просто обрабатывает входную строку как базовое число 36 и преобразует в десятичную, а затем обрабатывает особый NOслучай.

Выход:

$ ч А
10
$ ч Б
11
$ h CAT
15941
$ ч НЕТ
44596
$ ч ДА
44596
$ h ZZZ
46655
$

5

Рубин, 51 байт

h=->s{d=s.unpack('C*').join;d=~/896983|^7879$/?0:d}

код тестирования:

h=->s{d=s.unpack('C*').join;d=~/896983|^7879$/?0:d}

puts 'YES : '+h.call('YES').to_s # 0
puts 'NO : '+h.call('NO').to_s # 0
puts 'NOX : '+h.call('NOX').to_s # 787988
puts 'FNO : '+h.call('FNO').to_s # 707879
puts ''

values = Hash[]
n = 0
('A'..'Z').each{|c|
    values[c] = h.call(c)
    ('A'..'Z').each{|c2|
        values[c+c2] = h.call(c+c2)
        ('A'..'Z').each{|c3|
            values[c+c2+c3] = h.call(c+c2+c3)
            n += 1
        }
    }
}
puts 'tested '+n.to_s
duplicate = Hash.new()

values.each{|k, e|
    if duplicate.has_key?(e)
        puts 'duplicate : "'+k+'" = "'+duplicate[e].to_s+'" ('+e.to_s+')'
    else
        duplicate[e] = k
    end
}

выход :

YES : 0
NO : 0
NOX : 787988
FNO : 707879

tested 17576
duplicate : "YES" = "NO" (0)

5

Javascript ( ES6 ) 54 байта

f=s=>[x.charCodeAt()for(x of s)].join('')^7879||897296
f('YES'); // 897296
f('NO'); // 897296
f('MAYBE'); // -824036582

5

Ява - 94 77

int h=new BigInteger(s.getBytes()).intValue();return Math.abs(h-(h^5835548));

раскатали:

int hashCode(String s) {
    int h = new BigInteger(s.getBytes()).intValue();
    return Math.abs(h - (h ^ 5835548));
}

Повествование - для f(s) = BigInteger(s.getBytes()):

  • f("YES") xor f("NO") = 5835548
  • Так f("YES") xor 5835548 = f("NO")
  • Так f("YES") - (f("YES") xor 5835548) = f("NO") - (f("NO") xor 5835548)я прав?

Не можете ли вы встроить BigInteger?
Мафу

@mafutrct - ДА !!! Спасибо.
OldCurmudgeon

5

CJam, 15 байтов

q42b_*81991617%

Работает как решение для GolfScript ниже. Попробуйте онлайн.


GolfScript, 17 байт

42base.*81991617%

Этот подход основан на ответах nneonneo и Ilmari Karonen .

Как это устроено

42base    # Interpret the input string as a base 42 number.
          # "YES" is [ 89 69 83 ] in ASCII, so it becomes 42 * (42 * 89 + 69) + 83 = 159977.
          # "NO" is [ 78 79 ] in ASCII, so it becomes 42 * 78 + 79 = 3355.
          #
.*        # Square. "YES" becomes 25592640529, "NO" becomes 11256025.
          #
81991617% # "YES" becomes 11256025.

Выбор алгоритма

Начнем с того {b base}:h, что входная строка считается числом base-b. Пока b > 25, hinyective.

Мы получим столкновение для строк «YES» и «NO», если изменим hследующим образом:, {x base n}:hгде nэто делитель "YES" h "NO" h -.

К сожалению, это означает, что мы также получим столкновение, например, YETиNP . Чтобы предотвратить это, мы должны изменить число base-b нелинейным образом, прежде чем принимать модуль.

Самый короткий способ сделать это в GolfScript - это умножить число base-b на себя (т. Е. Возвести его в квадрат). hв настоящее время {base b .* n %}:h.

Осталось только найти подходящие значения для bиn . Мы можем сделать это грубой силой:

for((b=26;b<100;b++)){
    P=($(golfscript <<< "['YES' 'NO']{$b base.*}/-" | factor | cut -d\  -f 2-))

    for n in $(for((i=0;i<2**${#P[@]};i++)){
        for((n=1,j=0;j<${#P[@]};n*=${P[j]}**((i>>j)&1),j++)){ :;};echo $n;} | sort -nu);{
            [[ $n -ge 18277 && $(echo -n '' {A..Z}{,{A..Z}{,{A..Z}}} |
                golfscript <(echo "' '/[{$b base.*$n%}/].&,")) = 18278 ]] &&
            echo $b $n && break
    }
}

Кратчайшие возможные значения для b n :

37 92176978
42 81991617

тестирование

$ echo -n '' {A..Z}{,{A..Z}{,{A..Z}}} |
     golfscript <(echo '{42base.*81991617%}:h;" "/{.`"\t"+\h+puts}/') |
     sort -k 2n |
     uniq -Df 1
"NO"    11256025
"YES"   11256025

3

JavaScript (ES6) - 38 символов (33 символа функции тела)

h=s=>(a=btoa(s))=="WUVT"|a=="Tk8="||+s

Тестовые случаи:

var l = console.log;
l(  h("YES")  );                // 1
l(  h("NO")  );                 // 1
l(  h("ABC")  );                // NaN     
l(  h("WIN")  );                // NaN
l(  h("YES") === h("NO")  );    // true
l(  h("ABC") === h("WIN")  );   // false
l(  h("WIN") === h("YES")  );   // false

l(  NaN === NaN  );             // false

Объяснение:

Прежде всего, позвольте мне представить вам NaN- «Не число» - в JavaScript. Это число:

typeof NaN  // number

Как:

typeof 42   // number

Его особенность в том, что он никогда не сравнится с собой . Моя функция возвращает, 1если строка является YESили NO, и NaNдля любой другой строки.

Таким образом, это не нарушает правила, потому что для любой другой строки не будет коллизии хеша;) ( NaN !== NaNпоказано выше в тестовых примерах).

И моя мечта сбылась: победить Bash, Perl и Ruby по длине кода!

Код Ungolfed:

h =  // h is a function 
s => // s = string argument

( ( a = btoa(s) )  ==  "WUVT" | a == "Tk8=" )
        ^-- returns some value stored in `a`

Если это значение "WUVT"или "Tk8=", верните 1. Остальное, возвращение

+s // parseInt(s, 10)

который был бы NaN.


2
NaN может быть числом, но это не "целое число" в любом смысле этого слова.
Пауло Эберманн

2
@ PaŭloEbermann Из вики : «Целое число - это число , написанное без дробного компонента». Вопрос прямо не говорит о том, что целое число должно быть ^\d+$. И JS относится к NaNчислу. Вы можете умножить его на число, сложить, разделить, вычесть так же, как с числами. Это особое свойство JavaScript. Там нет никакого вреда в использовании этого. Это то, что мы называем изменением правил ;)
Гауранг Тандон

1
Я мог бы использовать Object.is()и утверждать, что это все еще столкновение ...
user2428118

1
@ user2428118 Спасибо, что сообщили Object.is, насколько мне известно. Я никогда этого не знал. Но я хотел бы, чтобы вы заметили, что OP использует ==для сравнения оператор равенства ( ), что гарантирует отсутствие коллизий хешей для любой строки, кроме «YES» или «NO».
Гауранг Тандон

2
Не обращая внимания на тот факт , что , утверждая , NaNне считается , как столкновение кажется дешевым, это решение имеет столкновение с строками NAчерез NPи YEQчерезYET
nderscore

2

Python 92

n=int("".join(map(str,map(ord,raw_input()))))    # hashing function
print n if 1+(n**2-904862*n)/7067329057 else-1   # input validation

Функция хеширования объединяет порядковые значения символов ASCII, а оператор print гарантирует, что два желаемых входа сталкиваются.


2

ECMAScript 6 (30 байт)

Я пытался избежать назначения переменных, возврата и ключевого слова функции, и это выглядит как отличный способ избежать всей этой ерунды (в некотором смысле это также похоже на функциональное программирование). В отличие от других решений, это не зависит от btoaили atob, что не ECMAScript 6, а HTML5. 0+необходимо, чтобы он мог анализировать произвольные строки.

a=>parseInt(0+a,36)-852||43744

1
Приятно! Я не знал, что они добавили другие базы для parseInt. Вы можете сократить много байтов, хотя. :)a=>parseInt(0+a,36)-852||43744
nderscore

@nderscore: Спасибо за предложение. Это действительно улучшило мой сценарий.
Конрад Боровски

2

Ява - 45 (или 62?)

Я понятия не имею, как правильно оценить, учитывая, что нужно для запуска программы на Java, нужно ли включать определение функции? Не стесняйтесь редактировать и корректировать мой счет соответствующим образом. В настоящее время я забиваю так же, как и ответ @OldCurmudgeon. Добавьте 17 для, int h(String t){}если это требуется:

int h=t.hashCode();return h*h*3%1607172496;

Разряженный с испытательным ремнем безопасности:

import static org.junit.Assert.*;

import java.util.*;

import org.junit.Test;

public class YesNo {
  @Test
  public void testHashValue() {
    YesNo yesNo = new YesNo();
    Set<Integer> set = new HashSet<>();

    assertEquals(yesNo.hash("YES"), yesNo.hash("NO"));

    set.add(yesNo.hash(""));
    for(char i = 'A'; i <= 'Z'; i++) {
      set.add(yesNo.hash("" + i));
      for(char j = 'A'; j <= 'Z'; j++) {
        set.add(yesNo.hash("" + i + j));
        for(char k = 'A'; k <= 'Z'; k++) {
          set.add(yesNo.hash("" + i + j + k));
        }
      }
    }
    assertEquals(18278, set.size());
  }

  int hash(String toHash) {
    int hashValue=toHash.hashCode();
    return hashValue*hashValue*3%1607172496;
  }
}

1

И проигравший это ...

Конвейер, 145 символов

 I
>#<
 26*)2**\88
 >========*
 ^    \ \+-
 ^=====#==<
5**222P:
5======<
5***26*)*(\P\:@e25*:*)4*,F
>==============#=========
             P,F

По сути, эта программа делает что-то вроде базовых 26 символов. После этого он проверяет, равен ли хеш-код 12999 (хэш-код YES) и, если это так, выдает 404 (хэш-код NO), иначе он просто распечатает хеш-код.

Conveyor - это язык, созданный мной, который в настоящее время находится на стадии бета-тестирования, но его переводчик, а также некоторые примеры и исходный код можно найти здесь: https://github.com/loovjo/Conveyor.


0

C # 4.5 (112 байт)

int h(string s){int code=s.Select((v,i)=>((int)v)<<(2*(i-1))).Sum();return(code|1073742225)|(code|-2147483569);}

Рабочая (?) Версия попытки подземного монорельса, в C #. Объединяет байты в строке в 32-разрядное целое число (работает только до 4 символов), затем сравнивает результат ИЛИ с результатом для «ДА» и «НЕТ» соответственно, а затем ИЛИ вместе.

Хотя в какой-то момент он может столкнуться, это не должно происходить ни за какие ^ [AZ] {2,3} $, кроме «ДА» и «НЕТ».


Ваша хеш-функция будет иметь гораздо больше коллизий. Ваша "хэш-функция" по существу игнорирует много битов в конкатенации. Все пары строк, которые отличаются только этими битами, будут иметь одинаковый хэш-код.
Паŭло Эберманн

0

Без комментариев - 31 (содержание функции: 26)

'=|*==|,,|+|"#|[|,  |+|-%3|]*|:

Довольно простое решение. ;) Работает для всех без исключения строк UTF-8.

ОБЪЯСНЕНИЕ: ' это, очевидно, функция. Во-первых, он проверяет, *равен ли (это ввод) |,,|+|"#|( |NO|). Если это так, он возвращает |, |+|-%3|( |YES|), иначе он просто возвращается *.


2
Я никогда не работал с No Comment, можно ли было бы объяснить, как ваше решение часто делается с непрозрачными ответами Golfscript, J или APL?
Кая

@Kaya О да, извините, я буду редактировать пост.
cjfaure

1
Не нужно извинений, мне просто любопытно, как это работает.
Кая

0

С 54

h(char *c){int d=*(int*)c-20302;return d*(d-5436939);}

Преобразовать строку в целое число - «NO» и умножить ее на то же значение + «NO» - «YES», чтобы получить 0 для «NO» и «YES» и ненулевое значение для любой другой строки в указанном диапазоне.

Все значения на компьютере с Windows 7, если есть какие-либо порядковые номера.



-1

CoffeeScript - 36

Должен возвращаться 1для YESи NO, и всякая искаженная ерунда atobпроизводит для всего остального, что не является строкой base64.

h=(s)->_=atob s;_ in["`D","4"]&&1||_

Эквивалент JavaScript ( не код JS от компилятора CS):

function h( s ) {
    var _ = atob( s );

    if( _ === "`D" || _ === "4" )
        return 1;
    else
        return _;
}

3
«Функция должна иметь целочисленное возвращаемое значение» - я полагаю, ваш возвращает значение, _когда ввод не «ДА» или «НЕТ».
Гауранг Тандон

-1

Вот супер хромая. ТАК ГЛАВНО, ЭТО НЕ ДАЖЕ РАБОТАЕТ

Python 2,7 - 79 байт

def h(s):n=sum(100**i*ord(c)for i,c in enumerate(s));return (n-7978)*(n-836989)

Сначала мы получаем сумму (значение ascii каждого символа) * 100 ^ (позиция этого символа в строке). Затем мы умножаем (этот результат - 7978) и (этот результат - 836989), чтобы получить наш окончательный ответ. 7978 и 836989 - это результаты для «ДА» и «НЕТ» первого бита, поэтому для ДА и НЕТ мы умножаем на 0.

Это не должно иметь каких-либо столкновений? Мне не хочется тестировать 18000 возможных контрпримеров, но если произошло непреднамеренное столкновение, я могу добавить еще 0, 100и тогда действительно не должно быть никаких столкновений.

Разочарован тем, что я не мог использовать lambdaдля этого, но я не хотел делать весь расчет дважды, поэтому мне пришлось сохранить его в переменной.

Пожалуйста, не позволяйте этой победе. Это супер хромая, и я этого не заслуживаю.


Не соответствует требованию «никаких других коллизий»: из 18277-строкового набора есть только 18012 уникальных хэшей, которые не должны иметь коллизий.
2004 г.

@ dan Черт, дай мне второй
подземный

1
@ Дэн, я не могу заставить его работать. Возможно, что-то не так с алгоритмом. Я не хочу удалять его, потому что кто-то другой может знать, что не так, но я оставлю записку
подземный

Это работает для меня, h = лямбда-ы: (hash (s) +997192582) * (hash (s) -480644903)
Лукас

как и определение хеш-функции, похожей на вашу, но с 99 ** i * int (c, 36)
Лукас
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.