0

有很多关于如何使用 JAVA 创建 MYSQL MD5 哈希的好帖子,但是是否有可能采用另一种方式 - 使用 SQL 来生成 java 所做的事情?

在 SQL 中:

Select MD5('secret') = 5ebe2294ecd0e0f08eab7690d2a6ee69

在 Java 中,MD5 算法产生: 94-6634-108-20-48-32-16-114-85118-112-46-90-18105

首先,我可以看到 Java 是十进制表示,因此将 SQL 输出配对并转换为 DECIMAL 给出: 9419034148236208224240142171118144210166238105

唯一相同的部分是前 2 和后 4。

任何人都对如何使用 SQL 生成 Java 生成的内容有想法?

4

1 回答 1

0

我没有完全解决这个问题,但希望这些提示会有所帮助:

在 Java 中,如果您获取 md.digest() 调用的直接结果,则您有一个字节数组。无需将其转换为字符串表示形式,只需将字节输出为整数。你会看到它们是:

94 -66 34 -108 -20 -48 -32 -16 -114 -85 118 -112 -46 -90 -18 105

因此,生成的字符串转换中的破折号不是分隔符,它们是算术符号。java 哈希是字节值的简单串联,作为(有符号的)整数。

当您选择 MD5('secret') 时,您会得到一串 32 个十六进制数字。我验证了如果在 Java 中,你将每个字节转换为它的十六进制表示,然后将它们连接起来,你会得到与 MySQL 返回相同的字符串。

因此,在我看来,您在 MySQL 中需要做的是迭代 Hex() 的结果,一次一个十六进制字符(可能使用 SUBSTRING()),将每个字符转换为十进制,然后将它们连接起来。

编辑 - 看起来你几乎做对了,但你需要将每对十六进制数字转换为字节而不是 int,例如,'0xbe' 是 -66,而不是 190

编辑 #2 - 我对在 MySQL 中执行此操作的相对困难程度很感兴趣,所以我坚持(开玩笑)。以下存储的函数似乎可以完成这项工作:

drop function if exists java_md5;
delimiter |
create function java_md5(secret VARCHAR(255)) 
  RETURNS VARCHAR(255) 
  DETERMINISTIC 
  BEGIN
    DECLARE result varchar(255);
    DECLARE md5String char(255);
    DECLARE pair char(2);
    DECLARE pairInt int;
    DECLARE idx int;
    set md5String = MD5(secret);

    set result = '';
    set idx = 1;
    WHILE(idx < 32) DO
      set pair = substring(md5String, idx, 2);
      set pairInt = ascii(unhex(pair));
      set pairInt = if(pairInt > 127, pairInt - 256, pairInt);
      set result = concat(result, pairInt);
      set idx = idx + 2;
    END WHILE;
    RETURN result; 
  END|
delimiter ;

select java_md5('secret');
于 2012-09-16T18:08:26.467 回答