MD5 в Oracle (DBMS_OBFUSCATION_TOOLKIT.MD5) - PullRequest
4 голосов
/ 05 мая 2011

Я пытаюсь составить функцию для получения хэшей MD5 из битов, которые я собрал здесь и там. Я хочу получить строчное шестнадцатеричное представление хеша. У меня есть это до сих пор:

CREATE OR REPLACE FUNCTION MD5 (
    CADENA IN VARCHAR2
) RETURN DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM
AS
BEGIN
    RETURN LOWER(
        RAWTOHEX(
            UTL_RAW.CAST_TO_RAW(
                DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING => CADENA)
            )
        )
    );
END;

Я не уверен насчет типа возвращаемого значения функции. DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM выглядит как правильный выбор, и, насколько я могу судить, он работает, как и ожидалось, но определение пакета для dbms_obfuscation_toolkit, отображаемое SQL Developer, показывает это:

SUBTYPE varchar2_checksum IS VARCHAR2(16);

Вывод имеет 32 символа, поэтому я должен что-то делать не так. Мои вопросы:

  • Какой правильный тип для оператора RETURN?
  • Я делаю ненужные преобразования для вычисления хэша?

Ответы [ 2 ]

10 голосов
/ 05 мая 2011

Вот, пожалуйста:

create or replace function getMD5(
  in_string in varchar2)
return varchar2
as
  cln_md5raw raw(2000);
  out_raw raw(16);
begin
  cln_md5raw := utl_raw.cast_to_raw(in_string);
  dbms_obfuscation_toolkit.md5(input=>cln_md5raw,checksum=>out_raw);
  -- return hex version (32 length)
  return rawtohex(out_raw);
end;

Длина 32 - это шестнадцатеричное представление необработанного значения (16).Или измените вышеприведенный вариант, чтобы вывести исходную версию и сохранить исходную версию в столбце RAW (используется меньше места, но в будущем вы будете выполнять преобразования rawtohex и hextoraw).

Cheers

5 голосов
/ 05 мая 2011

Особенностью Oracle PL / SQL является то, что параметры хранимых процедур и типы возвращаемых функций не могут быть ограничены.То есть у нас не может быть процедуры с такой сигнатурой:

SQL> create or replace procedure my_proc (p1 in varchar2(30))
  2  is
  3  begin
  4      null;
  5  end;
  6  /

Warning: Procedure created with compilation errors.

SQL> show error
Errors for PROCEDURE MY_PROC:

LINE/COL ERROR
-------- -----------------------------------------------------------------
1/34     PLS-00103: Encountered the symbol "(" when expecting one of the
         following:
         := . ) , @ % default character
         The symbol ":=" was substituted for "(" to continue.

SQL> create or replace procedure my_proc (p1 in varchar2)
  2  is
  3  begin
  4      null;
  5  end;
  6  /

Procedure created.

SQL>

Конечно, мы можем определить параметр процедуры, используя SUBTYPE, но Oracle ее проигнорирует.То же самое относится и к типам возвращаемых функций ...

SQL> create or replace package my_subtypes as
  2      subtype ltd_string is varchar2(30);
  3  end;
  4  /

Package created.

SQL> create or replace function my_func return my_subtypes.ltd_string
  2  is
  3  begin
  4      return lpad('a', 4000, 'a');
  5  end;
  6  /

Function created.

SQL> select length(my_func) from dual
  2  /

LENGTH(MY_FUNC)
---------------
           4000

SQL>

Единственный способ ограничения параметров и возвращаемых типов - объявлять переменные с использованием подтипов в хранимой процедуре.Используйте переменные в пакете и присвойте их параметрам OUT (или ВОЗВРАЩАЙТЕ переменную для функций).

Это довольно многословный способ сказать, что вы можете использовать DBMS_OBFUSCATION_TOOLKIT.VARCHAR2_CHECKSUM в своем коде, уверенный в том, чтоэто не помешает вашей функции вернуть 32 символа.

Однако это может смутить разработчиков, которые будут искать объявление SUBTYPE.В худшем случае эти люди будут использовать подтип для объявления своих собственных рабочих переменных со следующим трагическим результатом:

SQL> declare
  2      v my_subtypes.ltd_string;
  3  begin
  4      v := my_func;
  5  end;
  6  /
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 4


SQL>

Таким образом, лучше не использовать неподходящий подтип.Вместо этого объявите свое собственное.

...