2009-11-17 31 views
14

Tôi gặp sự cố khi tạo một băm sha1 của một hàng trong một lựa chọn trên cơ sở dữ liệu Oracle. Tôi đã thực hiện nó trong MSSQL như sau:Tạo một băm sha1 của một hàng trong Oracle

SELECT *,HASHBYTES('SHA1',CAST(ID as varchar(10)+ 
    TextEntry1+TextEntry2+CAST(Timestamp as varchar(10)) as Hash 
FROM dbo.ExampleTable 
WHERE ID = [foo] 

Tuy nhiên, tôi không thể tìm thấy chức năng tương tự để sử dụng khi làm việc với Oracle. Theo như googling của tôi đã mang lại cho tôi, tôi đoán dbms_crypto.hash_sh1 có một cái gì đó để làm với nó, nhưng tôi đã không thể quấn bộ não của tôi xung quanh nó ...

Bất kỳ con trỏ sẽ rất nhiều đánh giá cao.

Trả lời

23

Gói DBMS_CRYPTO là gói đúng để tạo băm. Theo mặc định, nó không được cấp cho PUBLIC, bạn sẽ phải cấp cho nó một cách cụ thể (GRANT EXECUTE ON SYS.DBMS_CRYPTO TO user1).

Kết quả của hàm này là datatype RAW. Bạn có thể lưu trữ nó trong một cột RAW hoặc chuyển đổi nó thành VARCHAR2 bằng cách sử dụng các chức năng RAWTOHEX hoặc UTL_ENCODE.BASE64_ENCODE.

Chức năng HASH bị quá tải để chấp nhận ba kiểu dữ liệu như đầu vào: RAW, CLOBBLOB. Do số rules of implicit conversion, nếu bạn sử dụng VARCHAR2 làm đầu vào, Oracle sẽ cố chuyển đổi thành RAW và rất có thể sẽ không thành công do chuyển đổi này chỉ hoạt động với chuỗi thập lục phân.

Nếu bạn sử dụng VARCHAR2 sau đó, bạn cần phải chuyển đổi các đầu vào cho một kiểu dữ liệu nhị phân hoặc một CLOB, ví dụ:

DECLARE 
    x RAW(20); 
BEGIN 
    SELECT sys.dbms_crypto.hash(utl_raw.cast_to_raw(col1||col2||to_char(col3)), 
           sys.dbms_crypto.hash_sh1) 
    INTO x 
    FROM t; 
END; 

bạn sẽ tìm thêm thông tin trong tài liệu của DBMS_CRYPTO.hash

+2

Cảm ơn sự giúp đỡ. Tôi đã phải sử dụng giá trị dbms_crypto.hash_sh1 là viết tắt của (số nguyên 3) thay vì hằng số để làm cho nó hoạt động khi thực hiện một SQL thông thường. CHỌN sys.dbms_crypto.hash (utl_raw.cast_to_raw (col1), 3) TỪ t; – PrometheusDrake

+2

Tôi không nghĩ rằng điều này là chính xác cho 11g R2. 'dbms_crypto.hash' dường như có 3 phiên bản quá tải cho' raw', 'blob' và' clob'. Giá trị 'varchar2' phải được chuyển đổi thành' raw' hoặc bằng 'utl_i18n.string_to_raw' hoặc' utl_raw.cast_to_raw'. Hoặc sử dụng 'clobs' cho dữ liệu ký tự. – user272735

+0

Điều gì sẽ xảy ra nếu có một số cột không có loại dữ liệu chuỗi? – ca9163d9

7

Các DBMS_crypto gói không hỗ trợ varchar2. Nó hoạt động với kiểu thô vì vậy nếu bạn cần một varchar2 bạn phải chuyển đổi nó. Dưới đây là một chức năng mẫu cho thấy cách thực hiện điều này:

declare 
    p_string varchar2(2000) := 'Hello world !'; 
    lv_hash_value_md5 raw (100); 
    lv_hash_value_sh1 raw (100); 
    lv_varchar_key_md5 varchar2 (32); 
    lv_varchar_key_sh1 varchar2 (40); 
begin 
    lv_hash_value_md5 := 
    dbms_crypto.hash (src => utl_raw.cast_to_raw (p_string), 
         typ => dbms_crypto.hash_md5); 

    -- convert into varchar2 
    select lower (to_char (rawtohex (lv_hash_value_md5))) 
    into lv_varchar_key_md5 
    from dual; 

    lv_hash_value_sh1 := 
    dbms_crypto.hash (src => utl_raw.cast_to_raw (p_string), 
         typ => dbms_crypto.hash_sh1); 

    -- convert into varchar2 
    select lower (to_char (rawtohex (lv_hash_value_sh1))) 
    into lv_varchar_key_sh1 
    from dual; 

    -- 
    dbms_output.put_line('String to encrypt : '||p_string); 
    dbms_output.put_line('MD5 encryption : '||lv_varchar_key_md5); 
    dbms_output.put_line('SHA1 encryption : '||lv_varchar_key_sh1); 
end; 
3

Bạn có thể xác định hàm này trong gói yêu thích của mình, tôi đã xác định trong utils_pkg.

FUNCTION SHA1(STRING_TO_ENCRIPT VARCHAR2) RETURN VARCHAR2 AS 
BEGIN 
RETURN LOWER(TO_CHAR(RAWTOHEX(SYS.DBMS_CRYPTO.HASH(UTL_RAW.CAST_TO_RAW(STRING_TO_ENCRIPT), SYS.DBMS_CRYPTO.HASH_SH1)))); 
END SHA1; 

Bây giờ để gọi nó là

SELECT UTILS_PKG.SHA1('My Text') AS SHA1 FROM DUAL; 

Câu trả lời là

SHA1 
-------------------------------------------- 
5411d08baddc1ad09fa3329f9920814c33ea10c0 

Bạn có thể chọn một cột từ một số bảng:

SELECT UTILS_PKG.SHA1(myTextColumn) FROM myTable; 

Thưởng thức!

Các vấn đề liên quan