mirror of
https://github.com/Qortal/qortal.git
synced 2025-03-14 19:42:32 +00:00
Added SHA-256 file digest utility methods.
These read the file in small chunks, to reduce memory.
This commit is contained in:
parent
f34bdf0f58
commit
a78af8f248
@ -1,5 +1,8 @@
|
||||
package org.qortal.crypto;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
@ -75,12 +78,74 @@ public abstract class Crypto {
|
||||
return digest(digest(input));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 32-byte SHA-256 digest of file passed in input.
|
||||
*
|
||||
* @param file
|
||||
* file in which to perform digest
|
||||
* @return byte[32] digest, or null if SHA-256 algorithm can't be accessed
|
||||
*
|
||||
* @throws IOException if the file cannot be read
|
||||
*/
|
||||
public static byte[] digest(File file) throws IOException {
|
||||
return Crypto.digest(file, 8192);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 32-byte SHA-256 digest of file passed in input, in hex format
|
||||
*
|
||||
* @param file
|
||||
* file in which to perform digest
|
||||
* @return String digest as a hexadecimal string, or null if SHA-256 algorithm can't be accessed
|
||||
*
|
||||
* @throws IOException if the file cannot be read
|
||||
*/
|
||||
public static String digestHexString(File file, int bufferSize) throws IOException {
|
||||
byte[] digest = Crypto.digest(file, bufferSize);
|
||||
|
||||
// Convert to hex
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (byte b : digest) {
|
||||
stringBuilder.append(String.format("%02x", b));
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 32-byte SHA-256 digest of file passed in input.
|
||||
*
|
||||
* @param file
|
||||
* file in which to perform digest
|
||||
* @param bufferSize
|
||||
* the number of bytes to load into memory
|
||||
* @return byte[32] digest, or null if SHA-256 algorithm can't be accessed
|
||||
*
|
||||
* @throws IOException if the file cannot be read
|
||||
*/
|
||||
public static byte[] digest(File file, int bufferSize) throws IOException {
|
||||
try {
|
||||
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
|
||||
FileInputStream fileInputStream = new FileInputStream(file);
|
||||
byte[] bytes = new byte[bufferSize];
|
||||
int count;
|
||||
|
||||
while ((count = fileInputStream.read(bytes)) != -1) {
|
||||
sha256.update(bytes, 0, count);
|
||||
}
|
||||
fileInputStream.close();
|
||||
|
||||
return sha256.digest();
|
||||
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException("SHA-256 message digest not available");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 64-byte duplicated digest of message passed in input.
|
||||
* <p>
|
||||
* Effectively <tt>Bytes.concat(digest(input), digest(input)).
|
||||
*
|
||||
* @param addressVersion
|
||||
*
|
||||
* @param input
|
||||
*/
|
||||
public static byte[] dupDigest(byte[] input) {
|
||||
|
@ -10,7 +10,12 @@ import org.qortal.utils.Base58;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
import org.bouncycastle.crypto.agreement.X25519Agreement;
|
||||
import org.bouncycastle.crypto.params.Ed25519PrivateKeyParameters;
|
||||
@ -40,6 +45,37 @@ public class CryptoTests extends Common {
|
||||
assertArrayEquals(expected, digest);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileDigest() throws IOException {
|
||||
byte[] input = HashCode.fromString("00").asBytes();
|
||||
|
||||
Path tempPath = Files.createTempFile("", ".tmp");
|
||||
Files.write(tempPath, input, StandardOpenOption.CREATE);
|
||||
|
||||
byte[] digest = Crypto.digest(tempPath.toFile());
|
||||
byte[] expected = HashCode.fromString("6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d").asBytes();
|
||||
|
||||
assertArrayEquals(expected, digest);
|
||||
|
||||
Files.delete(tempPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFileDigestWithRandomData() throws IOException {
|
||||
byte[] input = new byte[128];
|
||||
new Random().nextBytes(input);
|
||||
|
||||
Path tempPath = Files.createTempFile("", ".tmp");
|
||||
Files.write(tempPath, input, StandardOpenOption.CREATE);
|
||||
|
||||
byte[] fileDigest = Crypto.digest(tempPath.toFile());
|
||||
byte[] memoryDigest = Crypto.digest(input);
|
||||
|
||||
assertArrayEquals(fileDigest, memoryDigest);
|
||||
|
||||
Files.delete(tempPath);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublicKeyToAddress() {
|
||||
byte[] publicKey = HashCode.fromString("775ada64a48a30b3bfc4f1db16bca512d4088704975a62bde78781ce0cba90d6").asBytes();
|
||||
|
Loading…
x
Reference in New Issue
Block a user