简体   繁体   English

让Oracle的MD5与PHP的MD5相匹配

[英]Getting Oracle's MD5 to match PHP's MD5

I'm trying to compare an MD5 checksum generated by PHP to one generated by Oracle 10g. 我正在尝试将PHP生成的MD5校验和与Oracle 10g生成的校验和进行比较。 However it seems I'm comparing apples to oranges. 然而,似乎我正在将苹果与橙子进行比较。

Here's what I did to test the comparison: 这是我测试比较所做的:

//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];

The md5 function (seen in the query above) in Oracle uses the 'dbms_obfuscation_toolkit.md5' package(?) and is defined like this: 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;

What comes out on my PHP page is: 我的PHP页面出现的是:

29dbb90ea99a397b946518c84f45e016

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

Can anyone help me in getting the two to match? 任何人都可以帮助我让两者相匹配吗?

It returns raw bytes, you need to convert that into hex. 它返回原始字节,您需要将其转换为十六进制。

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

It appears that what's being printed from the Oracle query is the raw bytestream of the md5 checksum, mangled because most of those octets won't be ascii characters. 从Oracle查询中打印的内容似乎是md5校验和的原始字节流,因为大多数这些八位字节不是ascii字符。 Try converting it to hexadecimal first. 首先尝试将其转换为十六进制。

Create a function like the following: 创建如下函数:

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;

and call it like this: 并称之为:

select md5('foobar') from dual;

it seems that "dbms_obfuscation_toolkit.md5" does not really return in raw format, hence the need to call "utl_raw.cast_to_raw". 看来“dbms_obfuscation_toolkit.md5”并没有真正以原始格式返回,因此需要调用“utl_raw.cast_to_raw”。 I could be wrong though, there should be a better explanation for this. 我可能错了,应该有更好的解释。

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

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

I got the same "numeric or value error" and found that two functions together work: 我得到了相同的“数值或值错误”,发现两个函数一起工作:

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;

Then you can run this query to get your checksum: 然后,您可以运行此查询以获取校验和:

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

That second function does the same thing as issuing the SELECT statement provided by Bazz on the function you provide, but I prefer to not have to do the rawToHex --> lower conversion inside of every query. 第二个函数与在您提供的函数上发布Bazz提供的SELECT语句完全相同,但我更喜欢不必在每个查询中执行rawToHex - > lower转换。 That leaves too many things to potentially go wrong every time you use the query. 每次使用查询时都会出现太多可能出错的问题。 I think it may be faster too since it is compiled at creation time instead of at runtime, but I may be wrong about that. 我认为它可能更快,因为它是在创建时而不是在运行时编译的,但我可能错了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM