在 java 中使用 SHA-256 散列十六进制数
Hash a hexadecimal number using SHA-256 in java
我在 Java 中编写了一个使用 SHA-256 散列十六进制数的代码。请看我的代码。
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Test {
public static void main (String[] args) throws NoSuchAlgorithmException {
BigInteger x = new BigInteger("f35b", 16);
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(x.byteValue());
byte[] hashedXArray = md.digest();
BigInteger hashedX = new BigInteger(hashedXArray);
System.out.println(hashedX.toString(16));
}
}
它的结果是……
245843abef9e72e7efac30138a994bf6301e7e1d7d7042a33d42e863d2638811
然后我使用另一个带有 SHA-256 的第三方应用程序对相同的输入进行哈希处理。它的答案与上面的输出完全不同。这是...
cd05094b5c5a5b80386da4fcfdd20e6ef5d363d97834ac8705e9832e6bd97f39
我还是不明白为什么我的代码结果与十六进制“f35b”的sha256的实际值相差很大,我该如何解析我的代码?
不使用 BigInteger
:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
public class HashIt {
public static void main(String[] args) throws NoSuchAlgorithmException {
byte[] input = new byte[] { (byte) 0xf3, (byte) 0x5b };
System.out.println(toHexString(input));
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(input);
byte[] hashedXArray = md.digest();
System.out.println(toHexString(hashedXArray));
}
private static String toHexString(byte[] bytes) {
Formatter result = new Formatter();
try (result) {
for (var b : bytes) {
result.format("%02x", b & 0xff);
}
return result.toString();
}
}
}
输出:
f35b
cd05094b5c5a5b80386da4fcfdd20e6ef5d363d97834ac8705e9832e6bd97f39
如果输入必须为字符串,添加:
private static byte[] fromHexString(String text) {
assert text.length()%2 == 0 : "invalid text length";
byte[] result = new byte[text.length()/2];
for (int i = 0; i < text.length(); i += 2) {
result[i/2] = (byte) Integer.parseInt(text.substring(i, i+2), 16);
}
return result;
}
并调用 byte[] input = fromHexString("f35b");
只是众多解决方案中的一个
不使用BigInteger
的一个原因:
BigInteger x = new BigInteger("00001234", 16);
byte[] input = x.toByteArray();
System.out.println(Arrays.toString(input));
前导零被删除,导致
[18, 52]
或
BigInteger x = new BigInteger("FFFF", 16);
byte[] input = x.toByteArray();
System.out.println(Arrays.toString(input));
添加了额外的零(使其为正):
[0, -1, -1]
为什么得到错误的结果:
BigInteger x = new BigInteger("f35b", 16);
System.out.println(Integer.toHexString(x.byteValue()));
结果为5b
,即给定BigInteger
的低字节。
我在 Java 中编写了一个使用 SHA-256 散列十六进制数的代码。请看我的代码。
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class Test {
public static void main (String[] args) throws NoSuchAlgorithmException {
BigInteger x = new BigInteger("f35b", 16);
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(x.byteValue());
byte[] hashedXArray = md.digest();
BigInteger hashedX = new BigInteger(hashedXArray);
System.out.println(hashedX.toString(16));
}
}
它的结果是……
245843abef9e72e7efac30138a994bf6301e7e1d7d7042a33d42e863d2638811
然后我使用另一个带有 SHA-256 的第三方应用程序对相同的输入进行哈希处理。它的答案与上面的输出完全不同。这是...
cd05094b5c5a5b80386da4fcfdd20e6ef5d363d97834ac8705e9832e6bd97f39
我还是不明白为什么我的代码结果与十六进制“f35b”的sha256的实际值相差很大,我该如何解析我的代码?
不使用 BigInteger
:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
public class HashIt {
public static void main(String[] args) throws NoSuchAlgorithmException {
byte[] input = new byte[] { (byte) 0xf3, (byte) 0x5b };
System.out.println(toHexString(input));
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(input);
byte[] hashedXArray = md.digest();
System.out.println(toHexString(hashedXArray));
}
private static String toHexString(byte[] bytes) {
Formatter result = new Formatter();
try (result) {
for (var b : bytes) {
result.format("%02x", b & 0xff);
}
return result.toString();
}
}
}
输出:
f35b
cd05094b5c5a5b80386da4fcfdd20e6ef5d363d97834ac8705e9832e6bd97f39
如果输入必须为字符串,添加:
private static byte[] fromHexString(String text) {
assert text.length()%2 == 0 : "invalid text length";
byte[] result = new byte[text.length()/2];
for (int i = 0; i < text.length(); i += 2) {
result[i/2] = (byte) Integer.parseInt(text.substring(i, i+2), 16);
}
return result;
}
并调用 byte[] input = fromHexString("f35b");
只是众多解决方案中的一个
不使用BigInteger
的一个原因:
BigInteger x = new BigInteger("00001234", 16);
byte[] input = x.toByteArray();
System.out.println(Arrays.toString(input));
前导零被删除,导致
[18, 52]
或
BigInteger x = new BigInteger("FFFF", 16);
byte[] input = x.toByteArray();
System.out.println(Arrays.toString(input));
添加了额外的零(使其为正):
[0, -1, -1]
为什么得到错误的结果:
BigInteger x = new BigInteger("f35b", 16);
System.out.println(Integer.toHexString(x.byteValue()));
结果为5b
,即给定BigInteger
的低字节。