让Oracle的MD5与PHP的MD5相匹配

时间:2009-08-04 16:56:12

标签: php oracle md5

我正在尝试将PHP生成的MD5校验和与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];

Oracle中的md5函数(在上面的查询中看到)使用'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à 

任何人都可以帮助我让两者相匹配吗?

5 个答案:

答案 0 :(得分:14)

它返回原始字节,您需要将其转换为十六进制。

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

答案 1 :(得分:7)

看来,从Oracle查询打印的内容是md5校验和的原始字节流,因为大多数这些八位字节不是ascii字符。首先尝试将其转换为十六进制。

答案 2 :(得分: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”。我可能错了,应该有更好的解释。

答案 3 :(得分:2)

如果您想在Oracle中使用md5,可以使用以下方法:

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

答案 4 :(得分:1)

我得到了相同的“数字或值错误”,发现两个函数一起工作:

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;

第二个函数与在您提供的函数上发布Bazz提供的SELECT语句相同,但我更喜欢不必执行rawToHex - &gt;降低每个查询内部的转换率。每次使用查询时都会出现太多可能出错的问题。我认为它可能更快,因为它是在创建时而不是在运行时编译的,但我可能错了。