diff --git a/src/main/java/tracker/EnhancedInfoHashCalculator.java b/src/main/java/tracker/EnhancedInfoHashCalculator.java
new file mode 100644
index 0000000..ef837bc
--- /dev/null
+++ b/src/main/java/tracker/EnhancedInfoHashCalculator.java
@@ -0,0 +1,185 @@
+package tracker;
+
+import java.io.File;
+import java.nio.file.Files;
+import java.security.MessageDigest;
+import java.util.Map;
+import com.dampcake.bencode.Bencode;
+import com.dampcake.bencode.Type;
+
+/**
+ * Enhanced InfoHash calculator that matches qBittorrent's calculation
+ * 
+ * The key issues with infoHash calculation are:
+ * 1. Bencode libraries may encode data differently
+ * 2. The original torrent's info dictionary bytes should be preserved
+ * 3. Re-encoding might change the binary representation
+ */
+public class EnhancedInfoHashCalculator {
+    
+    /**
+     * Calculate infoHash by extracting the original info dictionary bytes
+     * from the torrent file, rather than re-encoding the parsed data
+     */
+    public static String calculateInfoHash(File torrentFile) throws Exception {
+        byte[] torrentData = Files.readAllBytes(torrentFile.toPath());
+        
+        // Find the info dictionary in the raw torrent data
+        // Look for the pattern "4:info" which indicates the start of the info dictionary
+        int infoStart = findInfoDictionary(torrentData);
+        if (infoStart == -1) {
+            throw new Exception("Could not find info dictionary in torrent file");
+        }
+        
+        // Extract the info dictionary bytes directly from the original torrent
+        byte[] infoBytes = extractInfoBytes(torrentData, infoStart);
+        
+        // Calculate SHA1 hash
+        MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
+        byte[] digest = sha1.digest(infoBytes);
+        
+        // Convert to hex string
+        StringBuilder sb = new StringBuilder();
+        for (byte b : digest) {
+            sb.append(String.format("%02x", b & 0xff));
+        }
+        
+        return sb.toString();
+    }
+    
+    /**
+     * Find the position of "4:info" in the torrent data
+     */
+    private static int findInfoDictionary(byte[] data) {
+        byte[] pattern = "4:info".getBytes();
+        
+        for (int i = 0; i <= data.length - pattern.length; i++) {
+            boolean found = true;
+            for (int j = 0; j < pattern.length; j++) {
+                if (data[i + j] != pattern[j]) {
+                    found = false;
+                    break;
+                }
+            }
+            if (found) {
+                return i;
+            }
+        }
+        return -1;
+    }
+    
+    /**
+     * Extract the info dictionary bytes from the original torrent data
+     */
+    private static byte[] extractInfoBytes(byte[] data, int infoStart) throws Exception {
+        // Skip "4:info" to get to the actual dictionary content
+        int dictStart = infoStart + 6; // "4:info".length()
+        
+        if (dictStart >= data.length || data[dictStart] != 'd') {
+            throw new Exception("Invalid info dictionary format");
+        }
+        
+        // Find the matching 'e' that closes the info dictionary
+        int dictEnd = findMatchingEnd(data, dictStart);
+        if (dictEnd == -1) {
+            throw new Exception("Could not find end of info dictionary");
+        }
+        
+        // Extract the info dictionary bytes (including 'd' and 'e')
+        int length = dictEnd - dictStart + 1;
+        byte[] infoBytes = new byte[length];
+        System.arraycopy(data, dictStart, infoBytes, 0, length);
+        
+        return infoBytes;
+    }
+    
+    /**
+     * Find the matching 'e' for a dictionary that starts with 'd'
+     */
+    private static int findMatchingEnd(byte[] data, int start) {
+        if (start >= data.length || data[start] != 'd') {
+            return -1;
+        }
+        
+        int depth = 0;
+        for (int i = start; i < data.length; i++) {
+            if (data[i] == 'd' || data[i] == 'l') {
+                depth++;
+            } else if (data[i] == 'e') {
+                depth--;
+                if (depth == 0) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+    
+    /**
+     * For comparison: calculate using the re-encoding method (your original approach)
+     */
+    public static String calculateInfoHashByReencoding(File torrentFile) throws Exception {
+        byte[] torrentData = Files.readAllBytes(torrentFile.toPath());
+        Bencode bencode = new Bencode();
+        
+        @SuppressWarnings("unchecked")
+        Map<String,Object> meta = bencode.decode(torrentData, Type.DICTIONARY);
+        @SuppressWarnings("unchecked")
+        Map<String,Object> info = (Map<String,Object>) meta.get("info");
+        
+        if (info == null) {
+            throw new Exception("No info dictionary found");
+        }
+        
+        // Re-encode the info dictionary
+        byte[] infoBytes = bencode.encode(info);
+        
+        // Calculate SHA1
+        MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
+        byte[] digest = sha1.digest(infoBytes);
+        
+        StringBuilder sb = new StringBuilder();
+        for (byte b : digest) {
+            sb.append(String.format("%02x", b & 0xff));
+        }
+        
+        return sb.toString();
+    }
+    
+    public static void main(String[] args) {
+        if (args.length != 1) {
+            System.out.println("Usage: java EnhancedInfoHashCalculator <torrent-file>");
+            return;
+        }
+        
+        File torrentFile = new File(args[0]);
+        if (!torrentFile.exists()) {
+            System.out.println("Torrent file not found: " + args[0]);
+            return;
+        }
+        
+        try {
+            System.out.println("=== InfoHash Calculation Comparison ===");
+            System.out.println("File: " + torrentFile.getName());
+            
+            String directHash = calculateInfoHash(torrentFile);
+            System.out.println("Direct extraction method: " + directHash);
+            System.out.println("Direct (uppercase):       " + directHash.toUpperCase());
+            
+            String reencodingHash = calculateInfoHashByReencoding(torrentFile);
+            System.out.println("Re-encoding method:       " + reencodingHash);
+            System.out.println("Re-encoding (uppercase):  " + reencodingHash.toUpperCase());
+            
+            if (directHash.equals(reencodingHash)) {
+                System.out.println("✓ Both methods produce the same result");
+            } else {
+                System.out.println("✗ Methods produce different results!");
+                System.out.println("This suggests the Bencode re-encoding is changing the data");
+            }
+            
+        } catch (Exception e) {
+            System.out.println("Error: " + e.getMessage());
+            e.printStackTrace();
+        }
+    }
+}
diff --git a/src/main/java/tracker/Tracker.java b/src/main/java/tracker/Tracker.java
index 1b38806..11e0265 100644
--- a/src/main/java/tracker/Tracker.java
+++ b/src/main/java/tracker/Tracker.java
@@ -291,25 +291,20 @@
             Path target = storageDir.resolve(seedid + "_" + filename);
             Files.copy(TTorent.toPath(), target, StandardCopyOption.REPLACE_EXISTING);
 
-            // attempt to parse infoHash, but don't fail if parsing fails
+            // Calculate infoHash using ISO_8859_1 encoding method to match qBittorrent
             String infoHash = null;
             try {
-                byte[] torrentData = Files.readAllBytes(target);
-                Bencode bencode = new Bencode();
-                @SuppressWarnings("unchecked")
-                Map<String,Object> meta = bencode.decode(torrentData, Type.DICTIONARY);
-                @SuppressWarnings("unchecked")
-                Map<String,Object> info = (Map<String,Object>) meta.get("info");
-                byte[] infoBytes = bencode.encode(info);
-                MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
-                byte[] digest = sha1.digest(infoBytes);
-                StringBuilder sb = new StringBuilder();
-                for (byte b1 : digest) {
-                    sb.append(String.format("%02x", b1));
-                }
-                infoHash = sb.toString();
+                infoHash = calculateInfoHashReencoding(target.toFile());
+                System.out.println("InfoHash (ISO_8859_1): " + infoHash);
             } catch (Exception e) {
                 System.err.println("Warning: could not parse torrent infoHash: " + e.getMessage());
+                // Fallback to direct extraction method
+                try {
+                    infoHash = calculateInfoHashDirect(target.toFile());
+                    System.out.println("InfoHash (Direct): " + infoHash);
+                } catch (Exception e2) {
+                    System.err.println("Warning: fallback infoHash calculation also failed: " + e2.getMessage());
+                }
             }
 
             EntityManager em = emf.createEntityManager();
@@ -387,4 +382,178 @@
             em.close();
         }
     }
+    
+    /**
+     * Calculate infoHash by extracting the original info dictionary bytes
+     * from the torrent file, rather than re-encoding the parsed data.
+     * This method preserves the original binary representation.
+     */
+    private String calculateInfoHashDirect(File torrentFile) throws Exception {
+        byte[] torrentData = Files.readAllBytes(torrentFile.toPath());
+        
+        // Find the info dictionary in the raw torrent data
+        int infoStart = findInfoDictionary(torrentData);
+        if (infoStart == -1) {
+            throw new Exception("Could not find info dictionary in torrent file");
+        }
+        
+        // Extract the info dictionary bytes directly from the original torrent
+        byte[] infoBytes = extractInfoBytes(torrentData, infoStart);
+        
+        // Debug: print first few bytes of info dict
+        System.out.print("Info dict starts with: ");
+        for (int i = 0; i < Math.min(20, infoBytes.length); i++) {
+            System.out.printf("%02x ", infoBytes[i] & 0xff);
+        }
+        System.out.println();
+        
+        // Calculate SHA1 hash
+        MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
+        byte[] digest = sha1.digest(infoBytes);
+        
+        // Convert to hex string
+        StringBuilder sb = new StringBuilder();
+        for (byte b : digest) {
+            sb.append(String.format("%02x", b & 0xff));
+        }
+        
+        return sb.toString();
+    }
+    
+    /**
+     * Correct method using ISO_8859_1 encoding for infohash calculation
+     * This matches qBittorrent's calculation method
+     */
+    private String calculateInfoHashReencoding(File torrentFile) throws Exception {
+        byte[] torrentData = Files.readAllBytes(torrentFile.toPath());
+        
+        // Use ISO_8859_1 charset for infohash calculation (as per BitTorrent specification)
+        Bencode bencodeInfoHash = new Bencode(java.nio.charset.StandardCharsets.ISO_8859_1);
+        
+        @SuppressWarnings("unchecked")
+        Map<String,Object> meta = bencodeInfoHash.decode(torrentData, Type.DICTIONARY);
+        @SuppressWarnings("unchecked")
+        Map<String,Object> info = (Map<String,Object>) meta.get("info");
+        
+        if (info == null) {
+            throw new Exception("No info dictionary found");
+        }
+        
+        // Re-encode the info dictionary using ISO_8859_1
+        byte[] infoBytes = bencodeInfoHash.encode(info);
+        
+        // Calculate SHA1 hash
+        MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
+        byte[] digest = sha1.digest(infoBytes);
+        
+        StringBuilder sb = new StringBuilder();
+        for (byte b : digest) {
+            sb.append(String.format("%02x", b & 0xff));
+        }
+        
+        return sb.toString();
+    }
+    
+    /**
+     * Find the position of "4:info" in the torrent data
+     */
+    private int findInfoDictionary(byte[] data) {
+        byte[] pattern = "4:info".getBytes();
+        
+        for (int i = 0; i <= data.length - pattern.length; i++) {
+            boolean found = true;
+            for (int j = 0; j < pattern.length; j++) {
+                if (data[i + j] != pattern[j]) {
+                    found = false;
+                    break;
+                }
+            }
+            if (found) {
+                return i;
+            }
+        }
+        return -1;
+    }
+    
+    /**
+     * Extract the info dictionary bytes from the original torrent data
+     */
+    private byte[] extractInfoBytes(byte[] data, int infoStart) throws Exception {
+        // Skip "4:info" to get to the actual dictionary content
+        int dictStart = infoStart + 6; // "4:info".length()
+        
+        if (dictStart >= data.length || data[dictStart] != 'd') {
+            throw new Exception("Invalid info dictionary format");
+        }
+        
+        // Find the matching 'e' that closes the info dictionary
+        int dictEnd = findMatchingEnd(data, dictStart);
+        if (dictEnd == -1) {
+            throw new Exception("Could not find end of info dictionary");
+        }
+        
+        // Extract the info dictionary bytes (including 'd' and 'e')
+        int length = dictEnd - dictStart + 1;
+        byte[] infoBytes = new byte[length];
+        System.arraycopy(data, dictStart, infoBytes, 0, length);
+        
+        return infoBytes;
+    }
+    
+    /**
+     * Find the matching 'e' for a dictionary that starts with 'd'
+     */
+    private int findMatchingEnd(byte[] data, int start) {
+        if (start >= data.length || data[start] != 'd') {
+            return -1;
+        }
+        
+        int depth = 0;
+        int i = start;
+        
+        while (i < data.length) {
+            byte b = data[i];
+            
+            if (b == 'd' || b == 'l') {
+                // Dictionary or list start
+                depth++;
+                i++;
+            } else if (b == 'e') {
+                // Dictionary or list end
+                depth--;
+                if (depth == 0) {
+                    return i;
+                }
+                i++;
+            } else if (b == 'i') {
+                // Integer: i<number>e
+                i++; // skip 'i'
+                while (i < data.length && data[i] != 'e') {
+                    i++;
+                }
+                if (i < data.length) i++; // skip 'e'
+            } else if (b >= '0' && b <= '9') {
+                // String: <length>:<string>
+                int lengthStart = i;
+                while (i < data.length && data[i] >= '0' && data[i] <= '9') {
+                    i++;
+                }
+                if (i < data.length && data[i] == ':') {
+                    // Parse length
+                    String lengthStr = new String(data, lengthStart, i - lengthStart);
+                    int length = Integer.parseInt(lengthStr);
+                    i++; // skip ':'
+                    i += length; // skip string content
+                } else {
+                    // Invalid format
+                    return -1;
+                }
+            } else {
+                // Unknown character
+                i++;
+            }
+        }
+        
+        return -1;
+    }
 }
\ No newline at end of file
