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();
+        }
+    }
+}
