Получение Oracle MD5 для соответствия PHP MD5

Я пытаюсь сравнить контрольную сумму MD5, сгенерированную PHP, с одной, созданной Oracle 10g. Однако кажется, что я сравниваю яблоки с апельсинами.

Вот что я сделал, чтобы проверить сравнение:

//md5 tests

  //php md5
  print md5('testingthemd5function');

  print '<br/><br/>';

  //oracle md5
  $md5query = "select md5hash('testingthemd5function') from dual";

  $stid = oci_parse($conn, $md5query);
  if (!$stid) {
   $e = oci_error($conn);
   print htmlentities($e['message']);
   exit;
  }

  $r = oci_execute($stid, OCI_DEFAULT);
  if (!$r) {
   $e = oci_error($stid);
   echo htmlentities($e['message']);
   exit;
  }

  $row = oci_fetch_row($stid); 
  print $row[0];

Функция md5 (см. выше) в Oracle использует пакет dbms_obfuscation_toolkit.md5 (?) и определяется следующим образом:

CREATE OR REPLACE FUNCTION PORTAL.md5hash (v_input_string in varchar2) return varchar2     
is
   v_checksum varchar2(20);
   begin
   v_checksum := dbms_obfuscation_toolkit.md5 (input_string => v_input_string);
   return v_checksum;
end;

Что происходит на моей странице PHP:

29dbb90ea99a397b946518c84f45e016

)Û¹©š9{"eÈOEà 

Может ли кто-нибудь помочь мне в достижении этих двух?

Ответ 1

Он возвращает сырые байты, вам нужно преобразовать их в шестнадцатеричный.

$x = unpack("H*", $row[0]); 
echo $x[1];

Ответ 2

Похоже, что то, что печатается из запроса Oracle, является необработанным байтом контрольной суммы md5, искаженным, потому что большинство этих октетов не будут символами ascii. Попробуйте сначала преобразовать его в шестнадцатеричный.

Ответ 3

Создайте функцию, подобную следующей:

create or replace
function md5( input varchar2 ) return sys.dbms_obfuscation_toolkit.varchar2_checksum as
begin
    return lower(rawtohex(utl_raw.cast_to_raw(sys.dbms_obfuscation_toolkit.md5( input_string => input ))));
end;

и назовите его следующим образом:

select md5('foobar') from dual;

кажется, что "dbms_obfuscation_toolkit.md5" действительно не возвращается в необработанном формате, поэтому необходимо вызвать "utl_raw.cast_to_raw". Я мог ошибаться, но должно быть лучшее объяснение этого.

Ответ 4

Если вы хотите иметь md5 в Oracle, вы можете использовать этот метод:

select lower(rawtohex(md5hash('foobar'))) from dual

Ответ 5

Я получил ту же "цифровую или значную ошибку" и обнаружил, что работают две функции:

CREATE OR REPLACE FUNCTION MD5RAW( v_input_string in varchar2 )
RETURN varchar2 IS
v_checksum varchar2( 32 );
BEGIN
    v_checksum := SYS.DBMS_OBFUSCATION_TOOLKIT.MD5( input_string => v_input_string );
    return v_checksum;
END;

CREATE OR REPLACE FUNCTION MD5HEX( v_input_string in varchar2 )
RETURN varchar2 IS
v_hex_value varchar2( 32 );
BEGIN
    SELECT  LOWER( RAWTOHEX( MD5RAW( v_input_string ) ) ) 
    INTO    v_hex_value
    FROM    dual;
    return v_hex_value;
END;

Затем вы можете запустить этот запрос, чтобы получить свою контрольную сумму:

SELECT md5hex( 'my string smoked your hash' ) FROM dual;

Эта вторая функция выполняет то же самое, что и выдавать инструкцию SELECT, предоставленную Bazz, в функции, которую вы предоставляете, но я предпочитаю не выполнять необработанное преобразование rawToHex → внутри каждого запроса. Это оставляет слишком много вещей, чтобы потенциально ошибиться каждый раз, когда вы используете запрос. Я думаю, что это может быть и быстрее, потому что он компилируется во время создания, а не во время выполнения, но я могу ошибаться.