Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

Apa algoritma yang digunakan oleh fungsi ORA_HASH?

Nah, jika "tampaknya digunakan" maka masuk akal untuk melakukan sedikit rekayasa balik dan memeriksa apa sebenarnya yang disebut dan membongkar kode fungsi tersebut.

Namun, jika Anda ingin mendalami internal Oracle, berikut ini mungkin bisa membantu.

Pertama-tama, Anda harus mencari tahu apa fungsi C internal yang dipanggil. Untuk melakukannya, Anda dapat mengeksekusi beberapa kode yang berjalan lama dalam satu sesi. Saya menjalankan ini

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

Ini juga bisa berupa kode PL/SQL, Anda hanya perlu memastikan bahwa Anda terus-menerus memanggil ora_hash.

Saat sedang berjalan

Saya menguji pada Windows dan sepertinya ora_hash adalah ...->evaopn2()->evahash() ->...

Sekarang mari kita google untuk evahash. Kami sangat beruntung karena ada file header di situs resmi https://oss.Oracle.com/projects/ocfs-tools/src/branches/new-dir-format/libocfs/Linux/inc/ocfshash.h dengan tautan ke evahash.

Dan akhirnya ada halaman dengan kode C yang sebenarnya http://burtleburtle.net/bob/hash/ evahash.html

Sejauh ini bagus, kami ingat bahwa kami dapat menggunakan fungsi C eksternal di Oracle jika kami membangunnya ke dalam perpustakaan (DLL di Windows).

Misalnya pada Win x64 saya jika saya mengubah tanda tangan fungsi menjadi

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

itu bisa berhasil dieksekusi dari Oracle. Tapi, seperti yang Anda lihat, tanda tangan sedikit berbeda dari ora_hash di Oracle. Fungsi ini menerima nilai, panjangnya, dan initvalnya (dapat berupa seed) sedangkan signature di Oracle adalah ora_hash(expr, max_bucket, seed_value).

Mari kita coba mengujiOracle

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

Tidak ada angka yang cocok. Jadi apa masalahnya?ora_hash menerima parameter dari hampir semua jenis (misalnya select ora_hash(sys.odcinumberlist(1,2,3)) from dual ) sementara fungsi C menerima nilai sebagai array byte. Ini berarti bahwa beberapa konversi terjadi sebelum pemanggilan fungsi. Jadi sebelum menggunakan fungsi hash C yang disebutkan, Anda harus mengetahui bagaimana nilai aktual diubah sebelum meneruskannya.

Anda dapat melanjutkan dengan rekayasa balik binari Oracle menggunakan IDA PRO + sinar hex tetapi itu mungkin memakan waktu berhari-hari. Belum lagi detail spesifik platform.

Jadi jika Anda ingin meniru ora_hash, opsi termudah adalah menginstal Oracle express edition dan menggunakannya untuk memanggil ora_hash.

Saya harap itu menarik. Semoga berhasil.

Perbarui

ora_hash dan dbms_utility.get_hash_value dapat dipetakan satu sama lain (lihat 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

Jika kita membuka isi paket dbms_utility kita akan melihat deklarasi berikut

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

dan

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

Ayo cari di Google untuk icd_hash dan kami dapat menemukan bahwa itu dipetakan ke _psdhsh (https://yurichev.com/blog/50/ ). Sekarang saatnya membongkar oracle.exe dan mengekstrak kode untuk _psdhsh dari itu. Mungkin saya akan meluangkan waktu untuk ini tahun depan.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pelajari Tentang Paket DBMS_OUTPUT di Oracle

  2. Cara mengkompilasi file sumber tambahan di cmake setelah proses build

  3. Menggunakan Layanan Heterogen Oracle® dengan Dua Sumber Data ODBC

  4. String kueri Oracle termasuk karakter tanda hubung

  5. Bandingkan dan masukkan data baru ke dalam tabel berdasarkan bulan