[Android] Add computeHash for opensubtitles id

Geoffrey Métais git at videolan.org
Fri Apr 15 12:01:07 CEST 2016


vlc-android | branch: master | Geoffrey Métais <geoffrey.metais at gmail.com> | Thu Apr 14 12:22:20 2016 +0200| [7e131d917b6c34faf9379e80a2580f56498213e4] | committer: Geoffrey Métais

Add computeHash for opensubtitles id

> https://code.videolan.org/videolan/vlc-android/commit/7e131d917b6c34faf9379e80a2580f56498213e4
---

 .../src/org/videolan/vlc/util/FileUtils.java       | 53 ++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/vlc-android/src/org/videolan/vlc/util/FileUtils.java b/vlc-android/src/org/videolan/vlc/util/FileUtils.java
index 78b7655..545e33d 100644
--- a/vlc-android/src/org/videolan/vlc/util/FileUtils.java
+++ b/vlc-android/src/org/videolan/vlc/util/FileUtils.java
@@ -44,9 +44,18 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.LongBuffer;
+import java.nio.channels.FileChannel;
 
 public class FileUtils {
 
+    /**
+     * Size of the chunks that will be hashed in bytes (64 KB)
+     */
+    private static final int HASH_CHUNK_SIZE = 64 * 1024;
+
     public interface Callback {
         void onResult(boolean success);
     }
@@ -240,4 +249,48 @@ public class FileUtils {
         File file = new File(path);
         return (file.exists() && file.canWrite());
     }
+
+    public static String computeHash(File file) {
+        long size = file.length();
+        long chunkSizeForFile = Math.min(HASH_CHUNK_SIZE, size);
+        long head = 0;
+        long tail = 0;
+        FileInputStream fis = null;
+        FileChannel fileChannel = null;
+        try {
+            fis = new FileInputStream(file);
+            fileChannel = fis.getChannel();
+            head = computeHashForChunk(fileChannel.map(FileChannel.MapMode.READ_ONLY, 0, chunkSizeForFile));
+
+            //Alternate way to calculate tail hash for files over 4GB.
+            ByteBuffer bb = ByteBuffer.allocateDirect((int)chunkSizeForFile);
+            int read;
+            long position = Math.max(size - HASH_CHUNK_SIZE, 0);
+            while ((read = fileChannel.read(bb, position)) > 0) {
+                position += read;
+            }
+            bb.flip();
+            tail = computeHashForChunk(bb);
+
+            return String.format("%016x", size + head + tail);
+        } catch (FileNotFoundException e1) {
+            e1.printStackTrace();
+            return null;
+        }
+        catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }finally {
+            Util.close(fileChannel);
+            Util.close(fis);
+        }
+    }
+
+    private static long computeHashForChunk(ByteBuffer buffer) {
+        LongBuffer longBuffer = buffer.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
+        long hash = 0;
+        while (longBuffer.hasRemaining())
+            hash += longBuffer.get();
+        return hash;
+    }
 }



More information about the Android mailing list