1. Basic Concepts
MD5 (Message-Digest Algorithm 5) is a widely used hash function that generates a 128-bit (16-byte) long “digital fingerprint” or hash value for each different file. This hash value can be seen as a unique identifier for the file, similar to an ID number. Its core function is to verify the integrity and authenticity of files, ensuring that they have not been tampered with during transmission or storage. Whether in software downloads, data transfers, or other scenarios requiring file integrity assurance, MD5 plays a crucial role.
2. Important Features
2.1 Avalanche Effect: The MD5 algorithm is highly sensitive; even a slight change in the file content will result in a significant change in the generated MD5 value. This feature allows for the quick identification of any unauthorized modifications to the file.
2.2 Irreversibility: The MD5 algorithm is a one-way hash function, meaning that the original file content cannot be derived from the MD5 value. This irreversibility ensures the privacy and security of the file content.
2.3 Uniqueness: In theory, different files are almost impossible to produce the same MD5 value. This high degree of uniqueness makes the MD5 value a reliable basis for verifying file integrity.
3. Basic Structure of the Algorithm
Input File → Chunk Processing → Four Rounds of Bitwise Operations → Concatenate Results → Generate 32-bit Hexadecimal Fingerprint
Practical Section (Java)
import java.io.File;import java.io.FileInputStream;import java.security.MessageDigest;import java.util.Scanner;public class EnhancedFileMD5Checker { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); System.out.println("=== File Integrity Verification Tool ==="); System.out.print("Please enter the file path to verify: "); String filePath = scanner.nextLine().trim(); try { // 1. Check if the file exists File file = new File(filePath); if (!file.exists() || !file.isFile()) { System.err.println("Error: File does not exist or path is invalid"); return; } // 2. Get the original MD5 value from user input System.out.print("Please enter the original MD5 value (32-bit hexadecimal): "); String originalMD5 = scanner.nextLine().trim(); // 3. Verify MD5 format if (!originalMD5.matches("[a-fA-F0-9]{32}")) { System.err.println("Error: Invalid MD5 format, should be 32-bit hexadecimal characters"); return; } // 4. Calculate the file's MD5 value (with progress display) System.out.println("\nStarting MD5 calculation, please wait..."); String calculatedMD5 = MD5HashUtil.calculateMD5Value(file); // 5. Display results System.out.println("\n===== Verification Results ====="); System.out.println("File Path: " + filePath); System.out.println("File Size: " + formatFileSize(file.length())); System.out.println("Calculated MD5: " + calculatedMD5); System.out.println("Original MD5: " + originalMD5); // 6. Integrity verification if (originalMD5.equalsIgnoreCase(calculatedMD5)) { System.out.println("\nFile integrity verification passed!"); } else { System.out.println("\nFile has been tampered with or corrupted!"); System.out.println("Difference: " + findFirstDifference(originalMD5, calculatedMD5)); } } catch (Exception e) { System.err.println(" An error occurred: " + e.getMessage()); } finally { scanner.close(); } } // Find the first difference position private static String findFirstDifference(String original, String calculated) { original = original.toLowerCase(); calculated = calculated.toLowerCase(); for (int i = 0; i < Math.min(original.length(), calculated.length()); i++) { if (original.charAt(i) != calculated.charAt(i)) { return String.format("Position %d: Original(%s) vs Calculated(%s)", i + 1, original.charAt(i), calculated.charAt(i)); } } return "No difference (same length but different content)"; } // Format file size private static String formatFileSize(long size) { if (size < 1024) return size + " B"; int exp = (int) (Math.log(size) / Math.log(1024)); char unit = "KMGTPE".charAt(exp-1); return String.format("%.2f %sB", size / Math.pow(1024, exp), unit); }}
import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class MD5HashUtil { /** * Calculate MD5 hash value based on the file * @param file * @return */ public static String calculateMD5Value(File file){ try { // Construct an MD5 object to encrypt the data MessageDigest md5 = MessageDigest.getInstance("MD5"); FileInputStream fileInputStream = new FileInputStream(file); byte[] buffer = new byte[8192]; int read = -1; while((read = fileInputStream.read(buffer)) != -1){ md5.update(buffer,0,read); } // Call the digest() method of the MD5 instance to generate a 16-byte (128-bit) hash value array, returning a byte array containing the hash value byte[] digest = md5.digest(); StringBuilder sb = new StringBuilder(32); for (byte b : digest) { // Convert byte to unsigned integer (0-255) sb.append(String.format("%02x",b & 0xff)); } return sb.toString(); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException e) { throw new RuntimeException(e); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }}
Execution Instructions
1. Preparation:
Create a test file test.txt (content can be arbitrary)
Compile and run: javac EnhancedFileMD5Checker.java && java EnhancedFileMD5Checker
2. Expected Output:
File Path: test.txt
Calculated MD5: 5d41402abc4b2a76b9719d911017c592
// Actual value depends on the original content of the file
MD5: 5d41402abc4b2a76b9719d911017c592
File integrity verification passed!
3. Verification of Tampering:
Modify the content of test.txt and run again
Observe the change in MD5 value and the verification failure prompt