1 using System.Security.Cryptography;
2 using System.Text;
3 using Microsoft.Build.Framework;
4 
5 namespace Microsoft.Build.Tasks
6 {
7     /// <summary>
8     /// Generates a hash of a given ItemGroup items. Metadata is not considered in the hash.
9     /// <remarks>
10     /// Currently uses SHA1. Implementation subject to change between MSBuild versions. Not
11     /// intended as a cryptographic security measure, only uniqueness between build executions.
12     /// </remarks>
13     /// </summary>
14     public class Hash : TaskExtension
15     {
16         private const string ItemSeparatorCharacter = "\u2028";
17 
18         /// <summary>
19         /// Items from which to generate a hash.
20         /// </summary>
21         [Required]
22         public ITaskItem[] ItemsToHash { get; set; }
23 
24         /// <summary>
25         /// Hash of the ItemsToHash ItemSpec.
26         /// </summary>
27         [Output]
28         public string HashResult { get; set; }
29 
30         /// <summary>
31         /// Execute the task.
32         /// </summary>
Execute()33         public override bool Execute()
34         {
35             if (ItemsToHash != null && ItemsToHash.Length > 0)
36             {
37                 StringBuilder hashInput = new StringBuilder();
38 
39                 foreach (var item in ItemsToHash)
40                 {
41                     hashInput.Append(item.ItemSpec);
42                     hashInput.Append(ItemSeparatorCharacter);
43                 }
44 
45                 using (var sha1 = SHA1.Create())
46                 {
47                     var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(hashInput.ToString()));
48                     var hashResult = new StringBuilder(hash.Length*2);
49 
50                     foreach (byte b in hash)
51                     {
52                         hashResult.Append(b.ToString("x2"));
53                     }
54 
55                     HashResult = hashResult.ToString();
56                 }
57             }
58 
59             return true;
60         }
61     }
62 }
63