From 00baea7c5c7bdddf6dd5aa1fae8edaf2ed7a6400 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Sat, 15 Jan 2022 10:05:13 +0100 Subject: [PATCH] Introduce BytesUtils --- .../src/org/argeo/util/BytesUtils.java | 41 +++++++++++++++ .../src/org/argeo/util/DigestUtils.java | 50 +++++++++---------- org.argeo.util/src/org/argeo/util/DirH.java | 6 +-- 3 files changed, 67 insertions(+), 30 deletions(-) create mode 100644 org.argeo.util/src/org/argeo/util/BytesUtils.java diff --git a/org.argeo.util/src/org/argeo/util/BytesUtils.java b/org.argeo.util/src/org/argeo/util/BytesUtils.java new file mode 100644 index 000000000..c8fc129bc --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/BytesUtils.java @@ -0,0 +1,41 @@ +package org.argeo.util; + +/** Utilities around byte arrays and byte buffers. */ +public class BytesUtils { + final private static char[] hexArray = "0123456789abcdef".toCharArray(); + + /** Convert two longs to a byte array with length 16. */ + public static byte[] toBytes(long long1, long long2) { + byte[] result = new byte[16]; + for (int i = 0; i < 8; i++) + result[i] = (byte) ((long1 >> ((7 - i) * 8)) & 0xff); + for (int i = 8; i < 16; i++) + result[i] = (byte) ((long2 >> ((15 - i) * 8)) & 0xff); + return result; + } + + public static void copyBytes(long long1, long long2, byte[] arr, int offset) { + assert arr.length >= 16 + offset; + for (int i = offset; i < 8 + offset; i++) + arr[i] = (byte) ((long1 >> ((7 - i) * 8)) & 0xff); + for (int i = 8 + offset; i < 16 + offset; i++) + arr[i] = (byte) ((long2 >> ((15 - i) * 8)) & 0xff); + } + + /** Converts a byte array to an hex String. */ + public static String toHexString(byte[] bytes) { + char[] hexChars = new char[bytes.length * 2]; + for (int j = 0; j < bytes.length; j++) { + int v = bytes[j] & 0xFF; + hexChars[j * 2] = hexArray[v >>> 4]; + hexChars[j * 2 + 1] = hexArray[v & 0x0F]; + } + return new String(hexChars); + } + + /** singleton */ + private BytesUtils() { + + } + +} diff --git a/org.argeo.util/src/org/argeo/util/DigestUtils.java b/org.argeo.util/src/org/argeo/util/DigestUtils.java index ce018007c..e1a19160b 100644 --- a/org.argeo.util/src/org/argeo/util/DigestUtils.java +++ b/org.argeo.util/src/org/argeo/util/DigestUtils.java @@ -1,5 +1,7 @@ package org.argeo.util; +import static org.argeo.util.BytesUtils.toHexString; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -23,29 +25,34 @@ public class DigestUtils { // TODO: make it configurable private final static Integer byteBufferCapacity = 100 * 1024;// 100 KB - public static byte[] sha1(byte[] bytes) { + public static byte[] sha1(byte[]... bytes) { try { MessageDigest digest = MessageDigest.getInstance(SHA1); - digest.update(bytes); + for (byte[] arr : bytes) + digest.update(arr); byte[] checksum = digest.digest(); return checksum; } catch (NoSuchAlgorithmException e) { - throw new IllegalArgumentException(e); + throw new UnsupportedOperationException("SHA1 is not avalaible", e); } } - public static String digest(String algorithm, byte[] bytes) { + public static byte[] digestAsBytes(String algorithm, byte[]... bytes) { try { MessageDigest digest = MessageDigest.getInstance(algorithm); - digest.update(bytes); + for (byte[] arr : bytes) + digest.update(arr); byte[] checksum = digest.digest(); - String res = encodeHexString(checksum); - return res; + return checksum; } catch (NoSuchAlgorithmException e) { - throw new IllegalArgumentException("Cannot digest with algorithm " + algorithm, e); + throw new UnsupportedOperationException("Cannot digest with algorithm " + algorithm, e); } } + public static String digest(String algorithm, byte[]... bytes) { + return toHexString(digestAsBytes(algorithm, bytes)); + } + public static String digest(String algorithm, InputStream in) { try { MessageDigest digest = MessageDigest.getInstance(algorithm); @@ -60,7 +67,7 @@ public class DigestUtils { } byte[] checksum = digest.digest(); - String res = encodeHexString(checksum); + String res = toHexString(checksum); return res; } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException("Cannot digest with algorithm " + algorithm, e); @@ -101,7 +108,7 @@ public class DigestUtils { MessageDigest digest = MessageDigest.getInstance(algorithm); digest.update(bb); byte[] checksum = digest.digest(); - String res = encodeHexString(checksum); + String res = toHexString(checksum); long end = System.currentTimeMillis(); if (debug) System.out.println((end - begin) + " ms / " + ((end - begin) / 1000) + " s"); @@ -116,11 +123,11 @@ public class DigestUtils { } public static String digest(String algorithm, Path path, long bufferSize) { - byte[] digest = digestRaw(algorithm, path, bufferSize); - return encodeHexString(digest); + byte[] digest = digestAsBytes(algorithm, path, bufferSize); + return toHexString(digest); } - public static byte[] digestRaw(String algorithm, Path file, long bufferSize) { + public static byte[] digestAsBytes(String algorithm, Path file, long bufferSize) { long begin = System.currentTimeMillis(); try { MessageDigest md = MessageDigest.getInstance(algorithm); @@ -181,21 +188,10 @@ public class DigestUtils { } } - final private static char[] hexArray = "0123456789abcdef".toCharArray(); - - /** - * From - * http://stackoverflow.com/questions/9655181/how-to-convert-a-byte-array-to - * -a-hex-string-in-java - */ + /** @deprecated Use {@link BytesUtils#toHexString(byte[])} instead */ + @Deprecated public static String encodeHexString(byte[] bytes) { - char[] hexChars = new char[bytes.length * 2]; - for (int j = 0; j < bytes.length; j++) { - int v = bytes[j] & 0xFF; - hexChars[j * 2] = hexArray[v >>> 4]; - hexChars[j * 2 + 1] = hexArray[v & 0x0F]; - } - return new String(hexChars); + return BytesUtils.toHexString(bytes); } } diff --git a/org.argeo.util/src/org/argeo/util/DirH.java b/org.argeo.util/src/org/argeo/util/DirH.java index b6d962f06..ce7172a12 100644 --- a/org.argeo.util/src/org/argeo/util/DirH.java +++ b/org.argeo.util/src/org/argeo/util/DirH.java @@ -68,14 +68,14 @@ public class DirH { } public void print(PrintStream out) { - out.print(DigestUtils.encodeHexString(digest)); + out.print(BytesUtils.toHexString(digest)); if (dirName.length > 0) { out.print(' '); out.print(new String(dirName, charset)); } out.print('\n'); for (int i = 0; i < hashes.length; i++) { - out.print(DigestUtils.encodeHexString(hashes[i])); + out.print(BytesUtils.toHexString(hashes[i])); out.print(' '); out.print(new String(fileNames[i], charset)); out.print('\n'); @@ -88,7 +88,7 @@ public class DirH { List fNames = new ArrayList<>(); for (Path file : files) { if (!Files.isDirectory(file)) { - byte[] digest = DigestUtils.digestRaw(algorithm, file, bufferSize); + byte[] digest = DigestUtils.digestAsBytes(algorithm, file, bufferSize); hs.add(digest); fNames.add(file.getFileName().toString()); } -- 2.30.2