You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FoxMagiskModuleManager/app/src/main/java/com/fox2code/mmm/utils/Hashes.java

166 lines
5.4 KiB
Java

package com.fox2code.mmm.utils;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;
import java.util.regex.Pattern;
public class Hashes {
private static final String TAG = "Hashes";
private static final char[] HEX_ARRAY = "0123456789abcdef".toCharArray();
private static final Pattern nonAlphaNum = Pattern.compile("[^a-zA-Z0-9]");
public static String bytesToHex(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] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars);
}
public static String hashMd5(byte[] input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
return bytesToHex(md.digest(input));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static String hashSha1(byte[] input) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
return bytesToHex(md.digest(input));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static String hashSha256(byte[] input) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
return bytesToHex(md.digest(input));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
public static String hashSha512(byte[] input) {
try {
MessageDigest md = MessageDigest.getInstance("SHA-512");
return bytesToHex(md.digest(input));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* Check if the checksum match a file by picking the correct
* hashing algorithm depending on the length of the checksum
*/
public static boolean checkSumMatch(byte[] data, String checksum) {
String hash;
if (checksum == null) return false;
switch (checksum.length()) {
case 0:
return true; // No checksum
case 32:
hash = Hashes.hashMd5(data); break;
case 40:
hash = Hashes.hashSha1(data); break;
case 64:
hash = Hashes.hashSha256(data); break;
case 128:
hash = Hashes.hashSha512(data); break;
default:
Log.e(TAG, "No hash algorithm for " +
checksum.length() * 8 + "bit checksums");
return false;
}
Log.d(TAG, "Checksum result (data: " + hash+ ",expected: " + checksum + ")");
return hash.equals(checksum.toLowerCase(Locale.ROOT));
}
/**
* Check if the checksum match a file by picking the correct
* hashing algorithm depending on the length of the checksum
*/
public static boolean checkSumMatch(InputStream data, String checksum) throws IOException {
String hash;
if (checksum == null) return false;
String checksumAlgorithm = checkSumName(checksum);
if (checksumAlgorithm == null) {
Log.e(TAG, "No hash algorithm for " +
checksum.length() * 8 + "bit checksums");
return false;
}
try {
MessageDigest md = MessageDigest.getInstance(checksumAlgorithm);
byte[] bytes = new byte[2048];
int nRead;
while ((nRead = data.read(bytes)) > 0) {
md.update(bytes, 0, nRead);
}
hash = bytesToHex(md.digest());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
Log.d(TAG, "Checksum result (data: " + hash + ",expected: " + checksum + ")");
return hash.equals(checksum.toLowerCase(Locale.ROOT));
}
public static boolean checkSumValid(String checksum) {
if (checksum == null) return false;
switch (checksum.length()) {
case 0:
default:
return false;
case 32:
case 40:
case 64:
case 128:
final int len = checksum.length();
for (int i = 0; i < len; i++) {
char c = checksum.charAt(i);
if (c < '0' || c > 'f') return false;
if (c > '9' && // Easier working with bits
(c & 0b01011111) < 'A') return false;
}
return true;
}
}
public static String checkSumName(String checksum) {
if (checksum == null) return null;
switch (checksum.length()) {
case 0:
default:
return null;
case 32:
return "MD5";
case 40:
return "SHA-1";
case 64:
return "SHA-256";
case 128:
return "SHA-512";
}
}
public static String checkSumFormat(String checksum) {
if (checksum == null) return null;
// Remove all non-alphanumeric characters
return nonAlphaNum.matcher(checksum.trim()).replaceAll("");
}
}