Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Варианты колизий хэш функции / 25 сообщений из 72, страница 1 из 3
07.06.2017, 19:09:34
    #39468142
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Сколько к примеру, такой вариант получения хэша, может содержать коллизий ?

И если они есть, то как коллизии будут построены ? И есть ли тема - сурсы, как можно построить тестер коллизий?

Сразу скажу, что сначала взял за аналог DJBX33A но там Ez и FY дают одинаковый хэш, притом алгоритм во много раз дольше работает на 4 секунды при 1000000000 с текстом 'Text 123'



Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
function Test_hash(const str: string): NativeUInt;
var
  pos, len: NativeUInt;
begin
  len := PNativeUInt(PByte(str) - 4)^;
  Result := 1;
  pos := 1;

  while len > 10 do
  begin
    Result := Result * len + (ord(str[pos]) + ord(str[pos + 1]) +
      ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
      ord(str[pos + 5]) + ord(str[pos + 6]) + ord(str[pos + 7]) +
      ord(str[pos + 8]) + ord(str[pos + 9]));

    DEC(len, 10);
    inc(pos, 10);
  end;

  case len of
    1:
      Result := Result * 1 + ord(str[pos]);
    2:
      Result := Result * 2 + (ord(str[pos]) + ord(str[pos + 1]));
    3:
      Result := Result * 3 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]));
    4:
      Result := Result * 4 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]));
    5:
      Result := Result * 5 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]));
    6:
      Result := Result * 6 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
        ord(str[pos + 5]));
    7:
      Result := Result * 7 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
        ord(str[pos + 5]) + ord(str[pos + 6]));
    8:
      Result := Result * 8 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
        ord(str[pos + 5]) + ord(str[pos + 6]) + ord(str[pos + 7]));
    9:
      Result := Result * 9 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
        ord(str[pos + 5]) + ord(str[pos + 6]) + ord(str[pos + 7]) +
        ord(str[pos + 8]));
    10:
      Result := Result * 10 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
        ord(str[pos + 5]) + ord(str[pos + 6]) + ord(str[pos + 7]) +
        ord(str[pos + 8]) + ord(str[pos + 9]));
  end;
end;
...
Рейтинг: 0 / 0
07.06.2017, 19:33:43
    #39468156
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Написал просто рандом, и нашёл из 1000 надомных от 1 до 10 символов

Hello: 505
IunG9G : 505
aMPM/y : 505
VM7jy6 : 505
aq_yJ : 505
YPOHGl : 505
wDRJr* : 505
D1P5J8v : 505
r1*xu9 : 505
BRj__7 : 505
uhB61*B : 505
QxwIk : 505
q0D2QV4 : 505
f/*xSi : 505
0.005501 сек.
...
Рейтинг: 0 / 0
07.06.2017, 20:23:43
    #39468174
Aleksandr Sharahov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
НяшикСколько к примеру, такой вариант получения хэша, может содержать коллизий ?

И если они есть, то как коллизии будут построены ? И есть ли тема - сурсы, как можно построить тестер коллизий?



Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
uses
   ShaDictionaries, ...;

procedure TForm1.bCollisionCountClick(Sender: TObject);
var
  i: integer;
  D: TShaIntegerBox;
begin
  D:=TShaIntegerBox.Create;
  for i:=0 to YourTestCount-1 do D.Add(YourHash(YourRandomString));
  ShowMessage(IntToStr(YourTestCount-D.Count));
  D.Free;
end;



ShaDictionaries лежит в исходниках тут http://guildalfa.ru/alsha/node/32
...
Рейтинг: 0 / 0
07.06.2017, 20:24:55
    #39468175
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
В общем, на 10000000 раз, приходиться около 13 тысяч коллизий...

Вполне неплохо я считаю

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
program ;

{$R *.res}

uses
  windows, system.SysUtils;


function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer; cdecl;
  varargs; external 'msvcrt.dll';


function GetRandomString(const ALen: Integer): string; inline;
const
  ValidChars =
    '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-/*_';
var
  I, len: Integer;
begin
  Result := '';
  for I := 1 to ALen do
    Result := Result + ValidChars[Random(67) + Low(string)];
end;

function Test_hash(const str: string): UInt64;
var
  pos, len: NativeUInt;
begin
  len := PNativeUInt(PByte(str) - 4)^;
  Result := 1;
  pos := 1;

  while len > 10 do
  begin
    Result := Result + (ord(str[pos]) + ord(str[pos + 1]) + ord(str[pos + 2]) +
      ord(str[pos + 3]) + ord(str[pos + 4]) + ord(str[pos + 5]) +
      ord(str[pos + 6]) + ord(str[pos + 7]) + ord(str[pos + 8]) +
      ord(str[pos + 9]));

    DEC(len, 10);
    inc(pos, 10);
  end;

  case len of
    1:
      Result := Result * 1 + ord(str[pos]);
    2:
      Result := Result * 2 + (ord(str[pos]) + ord(str[pos + 1]));
    3:
      Result := Result * 3 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]));
    4:
      Result := Result * 4 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]));
    5:
      Result := Result * 5 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]));
    6:
      Result := Result * 6 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
        ord(str[pos + 5]));
    7:
      Result := Result * 7 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
        ord(str[pos + 5]) + ord(str[pos + 6]));
    8:
      Result := Result * 8 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
        ord(str[pos + 5]) + ord(str[pos + 6]) + ord(str[pos + 7]));
    9:
      Result := Result * 9 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
        ord(str[pos + 5]) + ord(str[pos + 6]) + ord(str[pos + 7]) +
        ord(str[pos + 8]));
    10:
      Result := Result * 10 + (ord(str[pos]) + ord(str[pos + 1]) +
        ord(str[pos + 2]) + ord(str[pos + 3]) + ord(str[pos + 4]) +
        ord(str[pos + 5]) + ord(str[pos + 6]) + ord(str[pos + 7]) +
        ord(str[pos + 8]) + ord(str[pos + 9]));
  end;
end;

procedure SaveToFile(const FileName: string; const Str: UnicodeString);
const
  CByteOrderMarkUTF16LittleEndian: array [1 .. 2] of Byte = ($FF, $FE);
var
  hFile: THandle;
  Unused: DWORD;
begin
  hFile := FileCreate(FileName);
  if hFile <> INVALID_HANDLE_VALUE then
    try
      WriteFile(hFile, CByteOrderMarkUTF16LittleEndian,
        Length(CByteOrderMarkUTF16LittleEndian), Unused, nil);

      WriteFile(hFile, Pointer(Str)^, Length(Str) * SizeOf(WideChar),
        Unused, nil);
    finally
      FileClose(hFile);
    end;
end;


var
  startTime, stopTime, iCounterPerSec: Int64;
  time: Single;
  I: Int64;
  Output: AnsiString;
  str, str2: string;
  GT, GT2: NativeUInt;

begin
  try

    QueryPerformanceCounter(startTime);
    str2 := '';
    GT := Test_hash('Hello');

    Writeln('Hello:   ' + inttostr(GT));
    for I := 0 to 10000000 - 1 do
    begin
      str := GetRandomString(Random(10 - 1) + 1);

      if GT = Test_hash(str) then
      begin
        str2 := str2 + #13 + str + '   :  ' + inttostr(GT);
      end;
    end;

    if QueryPerformanceCounter(stopTime) then
    begin
      QueryPerformanceFrequency(iCounterPerSec);

      time := (0 - startTime + stopTime) / iCounterPerSec;

      SetLength(Output, 15);

      SetLength(Output, sprintf(PAnsiChar(Output), '%f сек.', time));

      Writeln(Output);
    end;

    SaveToFile('Lexem.txt', str2);

    Readln;

    exit;
  except
    on E: Exception do

    begin
      Writeln(E.ClassName, ': ', E.Message);
      Readln;
    end;
  end;

end.

...
Рейтинг: 0 / 0
07.06.2017, 20:43:25
    #39468176
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
НяшикВ общем, на 10000000 раз, приходиться около 13 тысяч коллизий...
От набора ключей зависит. На последовательных ключах жуть. Подозрвеваю, что на словарях тоже будет много коллизий.
...
Рейтинг: 0 / 0
07.06.2017, 20:49:18
    #39468179
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Kazantsev AlexeyНяшикВ общем, на 10000000 раз, приходиться около 13 тысяч коллизий...
От набора ключей зависит. На последовательных ключах жуть. Подозрвеваю, что на словарях тоже будет много коллизий.

Соглашусь пожалуй... По вашей ссылке если заменить RawByteString на string то скорость как у моей. Да притом, без столько коллизий.. Точнее вообще не выявил...
...
Рейтинг: 0 / 0
07.06.2017, 20:50:23
    #39468180
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Kazantsev AlexeyОт набора ключей зависит.
От метода подсчёта тоже
...
Рейтинг: 0 / 0
07.06.2017, 20:51:39
    #39468181
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
НяшикПо вашей ссылке...
Это не ко мне ;)
...
Рейтинг: 0 / 0
07.06.2017, 20:52:21
    #39468182
white_nigger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Тестирование хеша на рандомных строках имеет ценность примерно равную сферическому коню
...
Рейтинг: 0 / 0
07.06.2017, 20:55:02
    #39468184
Aleksandr Sharahov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Няшик,

1. Имеет смысл использовать 32-битный хеш, будет меньше нагружать кеш процессора и, следовательно, работать быстрее.

2. В тесте не видно защиты от совпадающих строк. Имеет смысл генерировать возрастающую последовательность.

3. На больших объемах имеет смысл использовать более качественный генератор случайных чисел, например, отсюда http://guildalfa.ru/alsha/node/33
...
Рейтинг: 0 / 0
07.06.2017, 21:01:48
    #39468189
Kazantsev Alexey
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
white_niggerТестирование хеша на рандомных строках имеет ценность примерно равную сферическому коню
Этот хеш и на рандомных guid'ах даёт кучу коллизий (99.9% из 10 млн.)
...
Рейтинг: 0 / 0
07.06.2017, 21:37:29
    #39468196
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Aleksandr Sharahov1. Имеет смысл использовать 32-битный хеш, будет меньше нагружать кеш процессора и, следовательно, работать быстрее.


При UInt64 - 22.577654 сек.
При integer 19.693001 сек.

Всего лишь 2.884653 при 50000000 раз в цикле. Так что думаю, это не имеет большой роли




Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
function RSHash(const Name: string): integer; // UInt64 
var
  I: Integer;
begin;
  Result := 0;
  for I := 0 to Length(Name) - 1 do
  begin;
    Result := Result * 1041204193 + (ord(Name[I + 1]) + 1507220783);
  end;
  Result := Result * -1866451833;
end;




Насчёт ссылки с рандомом,
ShaRandomAsm - 20.962778 сек.
ShaRandom - 26.529922 сек.

А вот стандартный random - 18.421213 сек.

В чём профит ?? Не понимаю..



function GetRandomString(const ALen: Integer): string; inline;
const
ValidChars =
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-/*_АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя';
var
I, len: Integer;
begin
Result := '';
for I := 1 to ALen do
Result := Result + ValidChars[ShaRandomAsm (131) + Low(string)];
end;

...

for I := 0 to 50000000 - 1 do
begin

str := GetRandomString(ShaRandomAsm (10 - 1) + 1);

end;
...
Рейтинг: 0 / 0
07.06.2017, 22:04:38
    #39468202
Aleksandr Sharahov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
НяшикПри UInt64 - 22.577654 сек.
При integer 19.693001 сек.
Всего лишь 2.884653 при 50000000 раз в цикле. Так что думаю, это не имеет большой роли

Речь не о данном тесте. Его быстродействие нам по барабану.
А в реальном использовании ты свои хеши будешь где-то хранить.
И скорость их поиска будет сильно зависеть от их размера.


НяшикShaRandomAsm - 20.962778 сек.
ShaRandom - 26.529922 сек.
А вот стандартный random - 18.421213 сек.

В чём профит ?? Не понимаю..

Опять же быстродействие твоего теста нам по барабану.
Важно, чтобы генерируемая последовательность была качественной, без зависимостей или, хуже того, циклов.
...
Рейтинг: 0 / 0
07.06.2017, 22:07:37
    #39468204
Aleksandr Sharahov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Быстродействие отдельно оценивай.
Если функция вычисления хеша без ветвлений, то единственной строки достаточно.
...
Рейтинг: 0 / 0
07.06.2017, 22:14:41
    #39468206
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Aleksandr SharahovИ скорость их поиска будет сильно зависеть от их размера.

-__-

Код: pascal
1.
2.
	h := RSHash(str);
	Idx = h or ht->nTableMask;
...
Рейтинг: 0 / 0
07.06.2017, 22:18:31
    #39468208
Aleksandr Sharahov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Няшик,

ни о чем, полностью функцию поиска покажи
...
Рейтинг: 0 / 0
07.06.2017, 22:40:57
    #39468216
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Aleksandr SharahovНяшик,

ни о чем, полностью функцию поиска покажи

она либо секретна, либо ещё не написана
...
Рейтинг: 0 / 0
07.06.2017, 22:59:11
    #39468221
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
defecatorAleksandr SharahovНяшик,

ни о чем, полностью функцию поиска покажи

она либо секретна, либо ещё не написана


Было бы что показывать,я её вырвал из zend и через конвертер h2pas.exe приделал

https://github.com/php/php-src/blob/7cba31535cbf24c0b8a24ae094afd9ed670435b0/Zend/zend_hash.c#L473
...
Рейтинг: 0 / 0
07.06.2017, 23:15:55
    #39468225
Aleksandr Sharahov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Няшик,

нам как раз еще одной хеш-таблицы не хватало в той ветке )
...
Рейтинг: 0 / 0
07.06.2017, 23:45:07
    #39468229
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
В прошлый раз мы коллективно решили, что Седжвик даёт отличное распределение и приемлемую скорость. В Rapid.Generics используется модифицированный хеш Седжвика. Сначала хешатся четвёрки байт, потом миксуются результирующие 4 байта. Коллизий немного больше, зато скорость хеша несравнимая. Можешь посмотреть примеры в GetHashCode-функциях.
...
Рейтинг: 0 / 0
08.06.2017, 03:24:39
    #39468253
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
SOFT FOR YOU,

Да ну... Чего - то не верится, что она будет быстрее чем вот это

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
function RSHashInline(Name: string): Integer; inline;
var
  I: Integer;
  t: PWord;
begin;
  t := PWord(Name);
  Result := 0;

  while char(t^) <> #0 do
  begin
    Result := (Result * 1041204193) + (t^ + 1507220783);
    INC(t);
  end;

  Result := Result * -1866451833;
end;



А я выжил всё из функции
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
function RSHash(const Name: string): Integer;
var
  I: Integer;
begin;
  Result := 0;
  for I := 0 to Length(Name) - 1 do
  begin;
    Result := (Result * 1041204193) + (ord(Name[I + 1]) + 1507220783);
  end;
  Result := Result * -1866451833;
end;



И получил 0.120553 сек выигрыша.

Тестировал вот так
Код: pascal
1.
2.
3.
4.
    for I := 0 to 50000000 - 1 do
    begin
      src := RSHashInline('Text');
    end;




RSHash - 0.402344
RSHashInline - 0.281791
...
Рейтинг: 0 / 0
08.06.2017, 09:18:12
    #39468312
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Няшик,

А ты возьми для сравнения функцию из Rapid.Generics
...
Рейтинг: 0 / 0
08.06.2017, 09:32:13
    #39468319
SOFT FOR YOU
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
function RapidHashCode_UStr(const S: UnicodeString): Integer;
label
  hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7, hash8, hash9, hash10;
var
  Value: PByte;
  Count: NativeUInt;
  M: Integer;
begin
  if (Pointer(S) <> nil) then
  begin 
    Value := Pointer(S);
    Count := PInteger(@Value[-SizeOf(Integer)])^;
    Count := Count * 2 + 2;
    Count := Count and -4;

    Result := Integer(Count) + PInteger(@Value[Count - SizeOf(Integer)])^ * 63689;
    case (Count - 1) shr 2 of
     10: goto hash10;
      9: goto hash9;
      8: goto hash8;
      7: goto hash7;
      6: goto hash6;
      5: goto hash5;
      4: goto hash4;
      3: goto hash3;
      2: goto hash2;
      1: goto hash1;
      0: goto hash0;
    else
      Dec(Count);
      M := -1660269137;
      repeat
        Result := Result * M + PInteger(Value)^;
        Dec(Count, SizeOf(Integer));
        Inc(Value, SizeOf(Integer));
        M := M * 378551;
      until (Count <= 43);

      hash10:
        Result := Result * 631547855 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash9:
        Result := Result * -1987506439 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash8:
        Result := Result * -1653913089 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash7:
        Result := Result * -186114231 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash6:
        Result := Result * 915264303 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash5:
        Result := Result * -794603367 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash4:
        Result := Result * 135394143 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash3:
        Result := Result * 2012804575 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash2:
        Result := Result * -1092754919 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash1:
        Result := Result * -1660269137 + PInteger(Value)^;
      hash0:
    end;

    Inc(Result, ((Result shr 8) * 63689) + ((Result shr 16) * -1660269137) +
      ((Result shr 24) * -1092754919));
    Exit;
  end else
  begin
    Result := 0;
  end;
end;

...
Рейтинг: 0 / 0
08.06.2017, 09:42:48
    #39468329
Aleksandr Sharahov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Няшик,

на пустой строке RSHashInline обломится
...
Рейтинг: 0 / 0
08.06.2017, 11:04:43
    #39468401
Няшик
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Варианты колизий хэш функции
Aleksandr SharahovНяшик,

на пустой строке RSHashInline обломится

Да, точно
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
function RSHashInline(Name: string): Cardinal; inline;
var
  t: PChar;
begin;
  t := PChar(Name);
  Result := 0;

  while t^ <> #0 do
  begin
    Result := (Result * 1041204193) + (word(t^) + 1507220783);
    INC(t);

  end;

  Result := Result * -1866451833;
end;



SOFT FOR YOU
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
function RapidHashCode_UStr(const S: UnicodeString): Integer;
label
  hash0, hash1, hash2, hash3, hash4, hash5, hash6, hash7, hash8, hash9, hash10;
var
  Value: PByte;
  Count: NativeUInt;
  M: Integer;
begin
  if (Pointer(S) <> nil) then
  begin 
    Value := Pointer(S);
    Count := PInteger(@Value[-SizeOf(Integer)])^;
    Count := Count * 2 + 2;
    Count := Count and -4;

    Result := Integer(Count) + PInteger(@Value[Count - SizeOf(Integer)])^ * 63689;
    case (Count - 1) shr 2 of
     10: goto hash10;
      9: goto hash9;
      8: goto hash8;
      7: goto hash7;
      6: goto hash6;
      5: goto hash5;
      4: goto hash4;
      3: goto hash3;
      2: goto hash2;
      1: goto hash1;
      0: goto hash0;
    else
      Dec(Count);
      M := -1660269137;
      repeat
        Result := Result * M + PInteger(Value)^;
        Dec(Count, SizeOf(Integer));
        Inc(Value, SizeOf(Integer));
        M := M * 378551;
      until (Count <= 43);

      hash10:
        Result := Result * 631547855 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash9:
        Result := Result * -1987506439 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash8:
        Result := Result * -1653913089 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash7:
        Result := Result * -186114231 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash6:
        Result := Result * 915264303 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash5:
        Result := Result * -794603367 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash4:
        Result := Result * 135394143 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash3:
        Result := Result * 2012804575 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash2:
        Result := Result * -1092754919 + PInteger(Value)^;
        Inc(Value, SizeOf(Integer));
      hash1:
        Result := Result * -1660269137 + PInteger(Value)^;
      hash0:
    end;

    Inc(Result, ((Result shr 8) * 63689) + ((Result shr 16) * -1660269137) +
      ((Result shr 24) * -1092754919));
    Exit;
  end else
  begin
    Result := 0;
  end;
end;



Приятно удивлён, что она на 0.015429 сек медленнее чем RSHashInline ... Я когда первый раз на гите увидел, подумал будет всё хуже
...
Рейтинг: 0 / 0
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Варианты колизий хэш функции / 25 сообщений из 72, страница 1 из 3
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]