source

ORA_HASH 함수에 사용되는 알고리즘은 무엇입니까?

nicesource 2023. 7. 13. 20:54
반응형

ORA_HASH 함수에 사용되는 알고리즘은 무엇입니까?

작업 중인 응용 프로그램에서 UUID 문자열에 있는 함수(문서)를 호출하기 위해 데이터베이스를 호출하는 코드를 발견했습니다.이 작업을 수행하는 이유는 사용하는 것으로 보이는 다른 시스템에 서비스 호출을 하려면 값이 필요하기 때문입니다.ORA_HASH칸막이용.

▁the다▁know니▁would.ORA_HASH를 사용하여 Oracle은 물론 실제 데이터베이스에 액세스할 수 없는 애플리케이션에 대해 유사한 서비스 호출을 수행할 수 있습니다.지금까지 Oracle API 설명서에 해당하는 내용만 확인할 수 있었습니다.

분명히 말씀드리자면,복제해야 합니다.ORA_HASH왜냐하면 그것은 내 통제 밖의 다른 시스템이 사용하는 것이고, 나는 그 시스템과 통합해야 하기 때문입니다.네, MD5와 같은 정말 표준 알고리즘을 사용할 수 있다면 좋겠지만, 그게 아니라면 할 수 없습니다.ORA_HASH이불 속에 있어요

이외에 해시 알고리즘의 사용을 제안하는 답변 또는 의견ORA_HASH도움이 되지 않습니다.으로 이질은특다대것다입니한음에히문▁is다것▁this니▁specific에 대한 문제입니다.ORA_HASH일반적으로 해시 또는 파티셔닝이 없습니다.

ORA_HASH를 사용하는 것으로 보이는 다른 시스템

음, 만약 그것이 "사용하는 것처럼 보인다면" 약간의 역설계를 하고 정확히 무엇이 호출되는지 확인하고 함수의 코드를 분해하는 것이 타당합니다.

하지만 Oracle 내부에 대해 자세히 알아보려면 다음과 같은 방법이 도움이 될 수 있습니다.

우선 내부 C 함수가 무엇인지 파악해야 합니다.이를 위해 한 세션에서 긴 실행 코드를 실행할 수 있습니다.제가 실행했습니다.

select avg(ora_hash(rownum)) id from
(select rownum from dual connect by rownum <= 1e4),
(select rownum from dual connect by rownum <= 1e4);

PL/SQL 코드일 수도 있습니다. ora_hash를 계속 호출해야 합니다.

실행 중

Windows에서 테스트해 본 결과 ora_hash는...->evoopn2px->evahash()->...

이제 evahash를 검색해 보겠습니다.공식 사이트 https://oss.oracle.com/projects/ocfs-tools/src/branches/new-dir-format/libocfs/Linux/inc/ocfshash.h 에 evahash에 대한 링크가 있는 헤더 파일이 있기 때문에 우리는 매우 운이 좋았습니다.

그리고 마지막으로 실제 C 코드가 있는 페이지가 있습니다. http://burtleburtle.net/bob/hash/evahash.html

지금까지는 외부 C 기능을 라이브러리(Windows의 DLL)에 내장하면 Oracle에서 사용할 수 있다는 것을 기억하고 있습니다.

예를 들어 Winx64에서 함수 시그니처를 다음으로 변경하는 경우

extern "C" ub4 hash( ub1 *k, ub4 length, ub4 initval)

Oracle에서 성공적으로 실행할 수 있습니다.그러나 보시다시피 서명은 Oracle의 ora_hash와 약간 다릅니다.Oracle의 서명이 ora_hash(expr, max_bucket, seed_value)인 동안 이 함수는 값, 길이 및 initval(시드일 수 있음)을 허용합니다.

Oracle을 테스트해 보겠습니다.

SQL> select ora_hash(utl_raw.cast_to_raw('0'), power(2, 32) - 1, 0) oh1,
  2         ora_hash('0', power(2, 32) - 1, 0) oh2,
  3         ora_hash(0, power(2, 32) - 1, 0) oh3,
  4         ora_hash(chr(0), power(2, 32) - 1, 0) oh4
  5    from dual;

       OH1        OH2        OH3        OH4
---------- ---------- ---------- ----------
3517341953 3517341953 1475158189 4056412421

C

int main()
{
    ub1 ta[] = {0};
    ub1* t = ta;
    cout << hash(t, 1, 0) << endl;
    ub1 ta0[] = {'0'};
    ub1* t0 = ta0;
    cout << hash(t0, 1, 0) << endl;
    return 0;
}

1843378377
4052366646

일치하는 숫자가 없습니다.그럼뭐 문가요 인제hash? 또는 a_message는 를 허용합니다(: a_는거모매예변개허수용를합니다의형유든의가예eters▁of:▁accepts(:select ora_hash(sys.odcinumberlist(1,2,3)) from dualC 함수는 값을 바이트 배열로 받아들입니다.이것은 함수 호출 전에 변환이 발생한다는 것을 의미합니다.따라서 언급된 C 해시 함수를 사용하기 전에 실제 값이 변환되는 방법을 파악해야 합니다.

IDA PRO + 16진수를 사용하여 Oracle 바이너리의 역엔지니어링을 진행할 수 있지만 며칠이 걸릴 수 있습니다.플랫폼별 세부 사항은 말할 것도 없습니다.

따라서 ora_hash를 모방하고 싶다면 Oracle express 버전을 설치하고 ora_hash를 호출하는 데 사용하는 것이 가장 쉬운 옵션입니다.

재미있었으면 좋겠네요.행운을 빌어요.

갱신하다

ora_dll 및 dbms_dll.get_dll_value는 서로 매핑할 수 있습니다(https://jonathanlewis.wordpress.com/2009/11/21/ora_hash-function/) 참조).

SQL> select dbms_utility.get_hash_value('0', 0 + 1, 1e6 + 1) ha1,
  2         ora_hash('0', 1e6, 0) + 1 ha2
  3    from dual;

       HA1        HA2
---------- ----------
    338437     338437

dbms_utility의 패키지 본문을 풀면 다음 선언이 나타납니다.

  function get_hash_value(name varchar2, base number, hash_size number)
    return number is
  begin
    return(icd_hash(name, base, hash_size));
  end;

그리고.

  function icd_hash(name      varchar2,
                    base      binary_integer,
                    hash_size binary_integer) return binary_integer;
  pragma interface(c, icd_hash);

검색해 보겠습니다.icd_hash그리고 우리는 그것이 지도화되어 있다는 것을 찾을 수 있습니다._psdhsh(https://yurichev.com/blog/50/) .이제 오라클을 분해할 시간입니다.코드 실행 및 추출_psdhsh을 좀요.아마도 내년에는 이것에 시간을 쓸 것입니다.

이것은 ora_hash 뒤에 있는 실제 algo에 대한 OP 질문에 답하지 않습니다.다음은 pl/sql에서 ora_hash를 사용하는 예입니다(@JohnHeller 설명에 응답).

기능:

SQL> create or replace function get_ora_hash(i_str in varchar2, i_max_bucket in number default 4294967295, i_seed number default 0)
return number deterministic
parallel_enable
as
  rv number:= 0;
begin

select ORA_HASH(i_str, i_max_bucket, i_seed) 
into rv 
from dual;

return rv;

end;
Function created.

사용 방법:

SQL> declare
  l_val number;
begin
  l_val := get_ora_hash('test');
  dbms_output.put_line(l_val);
end;
 PL/SQL procedure successfully completed.

DBM 출력:

2662839991

또한 RESULT_CACH 또는 다른 기술을 사용하여 작업 속도를 더욱 높일 수 있습니다.

벌써 엄청 빨라요.예를 들어, 큰 테이블에서 100만 번 함수 호출:

SQL> set serveroutput on
SQL> declare
  l_val number;
  l_start_dte timestamp;
  l_end_dte timestamp;
  l_interval INTERVAL DAY(9) TO SECOND(9);
  l_cnt number := 0;
begin
  l_start_dte:= systimestamp;
  --for rec in (select object_name from dba_objects)
  for rec in (select name from my_big_table where rownum <= 1000000)
  loop
    l_cnt := l_cnt + 1;
    l_val := get_ora_hash(rec.name);
  end loop;
  l_end_dte:= systimestamp;
  l_interval := l_end_dte - l_start_dte;
  dbms_output.put_line('Rows processed: ' || l_cnt 
    || ', Start: ' || l_start_dte  
    || ', End: ' || l_end_dte 
    || ', Interval: ' || l_interval);
end;
Rows processed: 1000000, Start: 14-DEC-17 02.48.31.138212 PM, End: 14-DEC-17 02.48.41.148884 PM, Interval: +000000000 00:00:10.010672000
 PL/SQL procedure successfully completed.

기본적으로 초당 100,000개의 행이 있습니다. 여기에는 여러분이 걱정하는 모든 컨텍스트 스위치가 포함됩니다.

성능 때문에 ORA_HASH를 복제해야 하는 경우에는 성능 병목 현상이 다른 곳에 있을 수도 있습니다.

언급URL : https://stackoverflow.com/questions/45948266/what-is-the-algorithm-used-by-the-ora-hash-function

반응형