【问题标题】:Is there an equivalent of T-SQL's HASHBYTES('SHA1', VARBINARY(MAX)) in Java?Java中是否有等效于T-SQL的 HASHBYTES('SHA1', VARBINARY(MAX)) ?
【发布时间】:2020-06-19 20:13:21
【问题描述】:

我正在使用 org.apache.commons.codec.digest.DigestUtils 库来计算 Java 中的 SHA1 哈希。 DigestUtils.sha1Hex("0x808204E039EFB76D96D3780BB507674").

很遗憾,这与下面的 SQL 语句给出的结果不同?

select HASHBYTES('SHA1', CONVERT(VARBINARY(MAX),
0x808204E039EFB76D96D3780BB507674,1))

varbinary 的等价物是 Java 中的 byte[]。所以,我尝试了DigestUtils.sha1Hex("0x808204E039EFB76D96D3780BB507674".getBytes()),但这也没有帮助。请指导。

【问题讨论】:

    标签: java hash byte varbinary hashbytes


    【解决方案1】:

    不要使用getBytes()。它与解码十六进制值无关。

    getBytes() 使用底层系统的默认 字符集,为字符串中的每个字符返回一个或多个字节。该字符集几乎可以肯定是 UTF-8 或 windows -125x,这意味着您的字符串中的所有字符都将有一个对应的字节,这是由于这些字符集将字符转换为字节的方式。

    所以,你的字节数组会有这样的值,这绝对是不是你想要的:

    {
        56, // codepoint for the '8' character
        48, // codepoint for the '0' character
        56, // codepoint for the '8' character
        50, // codepoint for the '2' character
        48, // codepoint for the '0' character
        52, // codepoint for the '4' character
        69, // codepoint for the 'E' character
        // etc.
    }
    

    “Hex”是十六进制的缩写,或基数 16。在基数 16 中,两位数字表示一个字节值,即从 0 到 2⁸−1 的值。您需要将每两个数字解析为一个字节值。

    虽然有第三方实用程序可以做到这一点,但它非常简单,最好手动完成:

    String s = "0x808204E039EFB76D96D3780BB507674";
    
    // chop off "0x"
    s = s.substring(2);
    
    byte[] bytes = new BigInteger(s, 16).toByteArray();
    

    现在,字节数组将具有与您的十六进制数字表示的字节相对应的值:

    {
        8,      // 0x8
        8,      // 0x08
        32,     // 0x20
        78,     // 0x4E
        3,      // 0x03
        -98,    // 0x9E
        // etc.
    }
    

    【讨论】:

      猜你喜欢
      • 2010-09-16
      • 2012-12-18
      • 1970-01-01
      • 2012-08-26
      • 1970-01-01
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多