powered by simpleCommunicator - 2.0.50     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Особенности Hash()
4 сообщений из 4, страница 1 из 1
Особенности Hash()
    #39885106
SHS_SHS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток.
Понадобилось повторить на Delphi функцию hash() из FB. Поиск по форуму выдал это 14398246 . В интернете нашел такую реализацию для HashELF64:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
function HashELF64(const aBuf; aBufSize: Integer): Int64;
type
  TByteArray = array[0..MaxInt - 1] of Byte;
var
  i: Integer;
  x: Int64;
begin
  Result := 0;
  for i := 0 to aBufSize - 1 do
  begin
    Result := (Result shl 4) + TByteArray(aBuf)[i];
    x := Result and $F000000000000000;
    if (x <> 0) then
      Result := Result xor (x shr 56);
    Result := Result and (not x);
  end;
end;


если строка на входе до 20 символов, то все нормально, но после 20 результат hash() FB3.0 и Delphi отличаются.
Так например hash строки "12345678901234567890":
Код: pascal
1.
2.
8526506766684599104 - FB
 696865270170176576 - Delphi


Если изменить код так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
function HashELF64(const aBuf; aBufSize: Integer): Int64;
type
  TByteArray = array[0..MaxInt - 1] of Byte;
var
  i: Integer;
  x: Int64;
begin
  Result := 0;
  for i := 0 to aBufSize - 1 do
  begin
    Result := (Result shl 4) + TByteArray(aBuf)[i];
    if Result < 0 then // <========================= дописать это
    begin
      Result := Abs(Result);
      Continue;
    end;
    x := Result and $F000000000000000;
    if (x <> 0) then
      Result := Result xor (x shr 56);
    Result := Result and (not x);
  end;
end;


то для строки "12345678901234567890" hash становится одинаковым. Но это не решает проблему. Для более длинных строк hash разный. Я понимаю, что дело в переполнении Int64, но как подправить не догоняю.
...
Рейтинг: 0 / 0
Особенности Hash()
    #39885118
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SHS_SHSЯ понимаю, что дело в переполнении Int64

Нет, дело в том, что в Дельфи shr это логический сдвиг, а не арифметический. Знак не
расширяется в отличии от Си. А арифметического у неё нет. Используй деление.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Особенности Hash()
    #39885153
SHS_SHS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо. Сейчас работает.
Может кому пригодится:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
function HashELF64(const aBuf; aBufSize: Integer): Int64;
type
  TByteArray = array[0..MaxInt - 1] of Byte;
var
  i: Integer;
  x: Int64;
begin
  Result := 0;
  for i := 0 to aBufSize - 1 do
  begin
    Result := (Result shl 4) + TByteArray(aBuf)[i];
    x := Result and $F000000000000000;
    if (x <> 0) then
      Result := Result xor (x div $100000000000000); // Result := Result xor (x shr 56);
    Result := Result and (not x);
  end;
end;
...
Рейтинг: 0 / 0
Особенности Hash()
    #39968011
sysdba22
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кому надо, функция на TypeScript для Node или браузера:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
const hashELF64 = (s: string) => {
  let res = 0n;
  for (const c of [...s]) {
    res = (res << 4n) + BigInt(c.charCodeAt(0));
    const x = res & 0xF000000000000000n;
    if (x !== 0n) {
      res = res ^ (x >> 56n);
    }
    res = res & (~x);
  }
  return res;
};



Работает только с первыми 128 символами ASCII и та же проблема с переполнением, которую на не смог победить. Но, так как у меня строки до 14 символов, от которых вычисляется, то меня устраивает.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Особенности Hash()
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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