天天看點

[20160302]關于FULL_HASH_VALUE.txt

[20160302]關于FULL_HASH_VALUE.txt

--昨天想給firefox安裝一個電腦插件,無意中發現Calculate Hash的插件:

--它是基于檔案來計算MD5,SHA1,理論講這些算法是一樣的,也可以用它來計算FULL_HASH_VALUE值。

1.建立一個檔案内容如下:

select * from dept where deptno=10^@

--注意一些問題,因為oracle計算FULL_HASH_VALUE是sql串後面還要加入chr(0),而且在vim下普通的文本檔案,vim都會在最後補上0d0a(windows下)。

--是以首先要:set binary,然後轉換成16進制模式,輸入00,在切換回來儲存。

Filename    Size (bytes)    MD5                                 SHA1

a.txt        35             5dc43114e7b9dbbdd574aa4e31f15036    341d98827a8cb1c04095dfe768efe5577ec6b043

2.看看oracle計算的情況:

SCOTT@book> select * from dept where deptno=10;

    DEPTNO DNAME          LOC

---------- -------------- -------------

        10 ACCOUNTING     NEW YORK

--sql_id=4xamnunv51w9j

SCOTT@book> select sql_id,hash_value,sql_text from v$sql where sql_id='4xamnunv51w9j';

SQL_ID        HASH_VALUE SQL_TEXT

------------- ---------- ------------------------------------------------------------

4xamnunv51w9j  911274289 select * from dept where deptno=10

SCOTT@book> select name,full_hash_value from V$DB_OBJECT_CACHE where hash_value=911274289 and rownum=1;

NAME                                     FULL_HASH_VALUE

---------------------------------------- --------------------------------

select * from dept where deptno=10       1431c45dbddbb9e74eaa74d53650f131

--很明顯跟上面計算的不一樣。再仔細觀察可以發現oracle計算的FULL_HASH_VALUE結果,實際上颠倒一下。

--比如後面3650f131 ,颠倒一下31f15036,這樣正好對上。

$ cat md5_with_chr0.sql

-- md5.sql computes md5 hash and rearranges bytes for printing on Linux (Little Endian)

--         compare results with V$DB_OBJECT_CACHE.HASH_VALUE (11g)

-- Luca May 2012

-- Note user need execute on DBMS_OBFUSCATION_TOOLKIT

-- usage @md5 'string'

-- Example: @md5 'select 1 from dual'

-- calculated

column md5hash format a100

select lower(rawtohex(UTL_RAW.CAST_TO_RAW(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING =>'&1'||chr(0))))) md5hash from dual;

with calc as (

select lower(rawtohex(UTL_RAW.CAST_TO_RAW(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING =>'&1'||chr(0))))) md5hash from dual

)

select substr(md5hash,7,2)||substr(md5hash,5,2)||substr(md5hash,3,2)||substr(md5hash,1,2)||

       substr(md5hash,15,2)||substr(md5hash,13,2)||substr(md5hash,11,2)||substr(md5hash,9,2)||

       substr(md5hash,23,2)||substr(md5hash,21,2)||substr(md5hash,19,2)||substr(md5hash,17,2)||

       substr(md5hash,31,2)||substr(md5hash,29,2)||substr(md5hash,27,2)||substr(md5hash,25,2) calculated_full_hash

       from calc;

SCOTT@book> @ &r/md5_with_chr0.sql 'select * from dept where deptno=10'

MD5HASH

--------------------------------

5dc43114e7b9dbbdd574aa4e31f15036

CALCULATED_FULL_HASH

1431c45dbddbb9e74eaa74d53650f131

--這樣正好對上了。

--再來重溫一下hash_value,sql_id的計算。

--sql_id的計算是使用MD5算法進行哈希,生成一個128位的Hash Value(也就是FULL_HASH_VALUE 32位),其中低32位作為HASH VALUE顯示,SQL_ID則取了後64位。

--實際上sql_id使用32進制表示,hash_value使用10進制表示。

SELECT hash_value

      ,TO_CHAR (hash_value, 'xxxxxxxx') hex_hash_value

      ,full_hash_value

      ,SUBSTR (full_hash_value, -8) hash_x

  FROM GV$DB_OBJECT_CACHE

WHERE hash_value = 911274289 AND ROWNUM = 1;

HASH_VALUE HEX_HASH_ FULL_HASH_VALUE                  HASH_X

---------- --------- -------------------------------- ----------------

911274289  3650f131 1431c45dbddbb9e74eaa74d53650f131 3650f131

--對比上面的select sql_id,hash_value,sql_text from v$sql where sql_id='4xamnunv51w9j';hash_value對上。

select to_number(substr(full_hash_value,-16),'xxxxxxxxxxxxxxxxxxxx') sql_id10, full_hash_value

from GV$DB_OBJECT_CACHE  WHERE hash_value = 911274289 AND ROWNUM = 1;

            SQL_ID10 FULL_HASH_VALUE

-------------------- --------------------------------

5668471540087320881 1431c45dbddbb9e74eaa74d53650f131

select replace(wmsys.wm_concat(c),',') from (

select c from (

SELECT SUBSTR ('0123456789abcdfghjkmnpqrstuvwxyz', a + 1, 1) c,rownum rn

  FROM (WITH data (a, b)

             AS (SELECT MOD (&1, 32) a, TRUNC (&1 / 32) b FROM DUAL

                 UNION ALL

                 SELECT MOD (b, 32) a, TRUNC (b / 32) b

                   FROM data

                  WHERE b !=0

                  )

        SELECT a

          FROM data)) order by rn desc);

--帶入5668471540087320881

REPLACE(WMSYS.WM_CONCAT(C),',')

---------------------------------

4xamnunv51w9j

--sql_id 也可以對上。