Utils { @Nullable public static String getBinaryHash(File apk, String algo) { FileInputStream fis = null; try { MessageDigest md = MessageDigest.getInstance(algo); fis = new FileInputStream(apk); BufferedInputStream bis = new BufferedInputStream(fis); byte[] dataBytes = new byte[8192]; int nread; while ((nread = bis.read(dataBytes)) != -1) { md.update(dataBytes, 0, nread); } byte[] mdbytes = md.digest(); return toHexString(mdbytes).toLowerCase(Locale.ENGLISH); } catch (IOException e) { String message = e.getMessage(); if (message.contains("read failed: EIO (I/O error)")) { Utils.debugLog(TAG, "potential filesystem corruption while accessing " + apk + ": " + message); } else if (message.contains(" ENOENT ")) { Utils.debugLog(TAG, apk + " vanished: " + message); } } catch (NoSuchAlgorithmException e) { throw new IllegalArgumentException(e); } finally { closeQuietly(fis); } return null; }  static String getIconsDir(final Context context, final double dpiMultiplier); static File getImageCacheDir(Context context); static long getImageCacheDirAvailableMemory(Context context); static long getImageCacheDirTotalMemory(Context context); static void copy(InputStream input, OutputStream output); static boolean symlinkOrCopyFileQuietly(SanitizedFile inFile, SanitizedFile outFile); static void consumeStream(InputStream stream); static boolean copyQuietly(File inFile, File outFile); static void closeQuietly(Closeable closeable); static String getFriendlySize(long size); static String getAndroidVersionName(int sdkLevel); static String formatFingerprint(Context context, String fingerprint); @NonNull static Uri getLocalRepoUri(Repo repo); static Uri getSharingUri(Repo repo); static Uri getPackageUri(String packageName); static String calcFingerprint(String keyHexString); static String calcFingerprint(Certificate cert); static String getPackageSig(PackageInfo info); static Locale getLocaleFromAndroidLangTag(String languageTag); static DisplayImageOptions.Builder getDefaultDisplayImageOptionsBuilder(); static DisplayImageOptions getRepoAppDisplayImageOptions(); static void setIconFromRepoOrPM(@NonNull App app, ImageView iv, Context context); static String hashBytes(byte[] input, String algo); @Nullable static String getBinaryHash(File apk, String algo); static String toHexString(byte[] bytes); static int parseInt(String str, int fallback); @Nullable static String[] parseCommaSeparatedString(String values); @Nullable static String serializeCommaSeparatedString(@Nullable String[] values); static Date parseDate(String str, Date fallback); static String formatDate(Date date, String fallback); static Date parseTime(String str, Date fallback); static String formatTime(Date date, String fallback); static CharSequence formatAppNameAndSummary(String appName, String summary); static boolean isSafePackageName(@Nullable String packageName); static int daysSince(@NonNull Date date); static String formatLastUpdated(@NonNull Resources res, @NonNull Date date); static void debugLog(String tag, String msg); static void debugLog(String tag, String msg, Throwable tr); static String getVersionName(Context context); static PackageInfo getPackageInfo(Context context, String packageName); @SuppressWarnings("unused") @RequiresApi(api = 11) static List<Map<String, String>> dumpCursor(Cursor cursor); static int dpToPx(int dp, Context ctx); static int bytesToKb(long bytes); static int getPercent(long current, long total); static void showToastFromService(final Context context, final String msg, final int length); static void applySwipeLayoutColors(SwipeRefreshLayout swipeLayout); static boolean canConnectToSocket(String host, int port); static boolean isServerSocketInUse(int port); static final String FALLBACK_ICONS_DIR; }
@Test public void testGetBinaryHash() { File f = TestUtils.copyResourceToTempFile("largeRepo.xml"); assertEquals("df1754aa4b56c86c06d7842dfd02064f0781c1f740f489d3fc158bb541c8d197", Utils.getBinaryHash(f, "sha256")); f = TestUtils.copyResourceToTempFile("masterKeyIndex.jar"); assertEquals("625d5aedcd0499fe04ebab81f3c7ae30c236cee653a914ffb587d890198f3aba", Utils.getBinaryHash(f, "sha256")); f = TestUtils.copyResourceToTempFile("index.fdroid.2016-10-30.jar"); assertEquals("c138b503c6475aa749585d0e3ad4dba3546b6d33ec485efd8ac8bd603d93fedb", Utils.getBinaryHash(f, "sha256")); f = TestUtils.copyResourceToTempFile("index.fdroid.2016-11-10.jar"); assertEquals("93bea45814fd8955cabb957e7a3f8790d6c568eaa16fa30425c2d26c60490bde", Utils.getBinaryHash(f, "sha256")); }