Understanding the Role of Hash Functions in Data Integrity