powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Варианты колизий хэш функции
25 сообщений из 72, страница 1 из 3
Варианты колизий хэш функции
    #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
Варианты колизий хэш функции
    #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
Варианты колизий хэш функции
    #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
Варианты колизий хэш функции
    #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
Варианты колизий хэш функции
    #39468176
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НяшикВ общем, на 10000000 раз, приходиться около 13 тысяч коллизий...
От набора ключей зависит. На последовательных ключах жуть. Подозрвеваю, что на словарях тоже будет много коллизий.
...
Рейтинг: 0 / 0
Варианты колизий хэш функции
    #39468179
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyНяшикВ общем, на 10000000 раз, приходиться около 13 тысяч коллизий...
От набора ключей зависит. На последовательных ключах жуть. Подозрвеваю, что на словарях тоже будет много коллизий.

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

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

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

3. На больших объемах имеет смысл использовать более качественный генератор случайных чисел, например, отсюда http://guildalfa.ru/alsha/node/33
...
Рейтинг: 0 / 0
Варианты колизий хэш функции
    #39468189
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
white_niggerТестирование хеша на рандомных строках имеет ценность примерно равную сферическому коню
Этот хеш и на рандомных guid'ах даёт кучу коллизий (99.9% из 10 млн.)
...
Рейтинг: 0 / 0
Варианты колизий хэш функции
    #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
Варианты колизий хэш функции
    #39468202
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НяшикПри UInt64 - 22.577654 сек.
При integer 19.693001 сек.
Всего лишь 2.884653 при 50000000 раз в цикле. Так что думаю, это не имеет большой роли

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


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

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

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

-__-

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

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

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

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

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

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


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

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

нам как раз еще одной хеш-таблицы не хватало в той ветке )
...
Рейтинг: 0 / 0
Варианты колизий хэш функции
    #39468229
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В прошлый раз мы коллективно решили, что Седжвик даёт отличное распределение и приемлемую скорость. В Rapid.Generics используется модифицированный хеш Седжвика. Сначала хешатся четвёрки байт, потом миксуются результирующие 4 байта. Коллизий немного больше, зато скорость хеша несравнимая. Можешь посмотреть примеры в GetHashCode-функциях.
...
Рейтинг: 0 / 0
Варианты колизий хэш функции
    #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
Варианты колизий хэш функции
    #39468312
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшик,

А ты возьми для сравнения функцию из Rapid.Generics
...
Рейтинг: 0 / 0
Варианты колизий хэш функции
    #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
Варианты колизий хэш функции
    #39468329
Aleksandr Sharahov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшик,

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


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