Discuss / Java / 为啥我的SHA-1不一样

为啥我的SHA-1不一样

Topic source
MessageDigest md1 = MessageDigest.getInstance("SHA-1");
        md1.update("Hello".getBytes("UTF-8"));
        md1.update("World".getBytes("UTF-8"));
        byte[] result1 = md1.digest(); // 20 bytes: 6f44e49f848dd8ed27f73f59ab5bd4631b3f6b0d ???
        System.out.println(new BigInteger(1, result1).toString(16));

但是我输出是:db8ac1c259eb89d4a131b253bacfca5f319d54f2

哈哈

廖雪峰

#2 Created at ... [Delete] [Delete and Lock User]

以你的为准

0rez-naY

#3 Created at ... [Delete] [Delete and Lock User]
new BigInteger(1, result1).toString(16) 有个大坑:0开头的,0最终会被省略

廖雪峰

#4 Created at ... [Delete] [Delete and Lock User]

用String.format():

System.out.println(String.format("%040x", new BigInteger("0004e473f59ab5bd4639f848dd8ed27f1b3f6b0d", 16))); // 0004e473f59ab5bd4639f848dd8ed27f1b3f6b0d

朋友们

System.out.println(String.format("%040x", new BigInteger("0004e473f59ab5bd4639f848dd8ed27f1b3f6b0d", 16))); // 0004e473f59ab5bd4639f848dd8ed27f1b3f6b0d

这里面%040x的意思是:最小的字符数为40 ,注意这不是总数,输出可以超过此宽度,若不足则会主动补“0”。%x在String.format里面是显示十六进制整数。

你们可以将**%040x改成%099x**试试就知道了。

         System.out.println("注意看%#,#代表输出以0x开头,50是字符长度:" + String.format("%#50x", new BigInteger("0004e473f59ab5bd4639f848dd8ed27f1b3f6b0d", 16)));// 0004e473f59ab5bd4639f848dd8ed27f1b3f6b0d

刚看了看format方法,%040x,原来是格式化字符串的意思。

format(String format,object... args)  使用指定的格式字符串和参数返回格式化的字符串。

注意:如果result前面有0会在转换为BigInteger时丢失,因为BigInteger类在处理字符串时会忽略前导零,因为在数值上它们没有意义。

如果需要保留前导零,可以使用其他方法,如使用printf格式化补0到指定位数输出,或者直接使用字节数组。

package com.aotmd;
import java.math.BigInteger;


public class Main {
    public static void main(String[] args) throws Exception {
        String hexString = "000005bd4639f848dd8ed27f1b3f6b0d";
        byte[] result=hexStringToByteArray(hexString);
        //5bd4639f848dd8ed27f1b3f6b0d
        System.out.println(new BigInteger(1,result).toString(16));
        //如果知道输出的位数,可以使用printf:000005bd4639f848dd8ed27f1b3f6b0d
        System.out.printf("%032x\n",new BigInteger(1,result));
        //还可以这样直接传入16进制字符串:000005bd4639f848dd8ed27f1b3f6b0d
        System.out.printf("%032x\n",new BigInteger(hexString,16));
        //如果不知道,就直接用字节数组吧:000005bd4639f848dd8ed27f1b3f6b0d
        for (byte b : result) {
            System.out.printf("%02x",b);
        }
        System.out.println();
    }
    /**
     * 16进制字符串转换为字节数组。
     * @param hexString 16进制字符串
     * @return 字节数组
     */
    public static byte[] hexStringToByteArray(String hexString) {
        int len = hexString.length();
        byte[] byteArray = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            byteArray[i / 2] = (byte) (
                    (Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i+1), 16)
            );
        }
        return byteArray;
    }
}

  • 1

Reply